360mpgui V1.5.0.0 -

The Xbox 360 was famous for its backwards compatibility, and 360mpGUI honors that legacy. The tool includes functionality to handle original Xbox ISOs, allowing veterans to prepare their OG Xbox titles for play on modified 360 hardware.

Before diving into the specifics of version 1.5.0.0, it’s important to understand what 360mpgui is. The software is a graphical user interface (GUI) wrapper or front-end for command-line multimedia processing tools—most commonly associated with MP4Box, FFmpeg, or x264 encoders. The "360" in its name hints at its specialization: handling 360-degree video formats, equirectangular mapping, and spherical metadata. 360mpgui v1.5.0.0

However, 360mpgui is not limited to VR content. It also serves as a comprehensive multiplexer, demultiplexer, and transcoder for standard video files. Version 1.5.0.0 refines these capabilities further. The Xbox 360 was famous for its backwards

As of this writing, version 1.5.0.0 is the latest stable release. The developer community has hinted at future plans: Users are encouraged to report bugs via the

Users are encouraged to report bugs via the project’s GitHub or forum thread.

class PanoramaViewer(QWidget): def init(self, parent=None): super().init(parent) self.image = None self.pixmap = None self.angle_x = 0 # yaw self.angle_y = 0 # pitch self.last_pos = None self.setMinimumSize(400, 300) self.setStyleSheet("background-color: #1e1e1e; border: 1px solid #3c3c3c;")

def set_image(self, img_array):
    """Set new equirectangular image."""
    self.image = img_array
    self.angle_x = 0
    self.angle_y = 0
    self.update_view()
def update_view(self):
    if self.image is None:
        return
    h, w = self.image.shape[:2]
    # simulate simple 360° pan by cropping a shifted region
    crop_w = min(w, int(w * 0.7))
    crop_h = min(h, int(h * 0.7))
    start_x = int((self.angle_x / 360.0) * w) % w
    # pitch clamp
    pitch_clamp = max(-80, min(80, self.angle_y))
    start_y = int(((pitch_clamp + 90) / 180.0) * h) % h
# wrap horizontally
    if start_x + crop_w <= w:
        cropped = self.image[start_y:start_y+crop_h, start_x:start_x+crop_w]
    else:
        part1 = self.image[start_y:start_y+crop_h, start_x:w]
        part2 = self.image[start_y:start_y+crop_h, 0:(start_x+crop_w)-w]
        cropped = np.hstack((part1, part2))
# resize to widget size
    img = cv2.resize(cropped, (self.width(), self.height()))
    rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    h, w, ch = rgb.shape
    bytes_per_line = ch * w
    qt_img = QImage(rgb.data, w, h, bytes_per_line, QImage.Format_RGB888)
    self.pixmap = QPixmap.fromImage(qt_img)
    self.update()
def paintEvent(self, event):
    if self.pixmap:
        painter = QPainter(self)
        painter.drawPixmap(0, 0, self.pixmap)
def mousePressEvent(self, event):
    if event.button() == Qt.LeftButton:
        self.last_pos = event.pos()
def mouseMoveEvent(self, event):
    if self.last_pos is not None:
        dx = event.x() - self.last_pos.x()
        dy = event.y() - self.last_pos.y()
        self.angle_x = (self.angle_x + dx) % 360
        self.angle_y = max(-90, min(90, self.angle_y + dy))
        self.update_view()
        self.last_pos = event.pos()
def mouseReleaseEvent(self, event):
    self.last_pos = None
def resizeEvent(self, event):
    if self.image is not None:
        self.update_view()