aboutsummaryrefslogtreecommitdiffstats
path: root/examples/multimedia/player/player.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimedia/player/player.py')
-rw-r--r--examples/multimedia/player/player.py194
1 files changed, 194 insertions, 0 deletions
diff --git a/examples/multimedia/player/player.py b/examples/multimedia/player/player.py
new file mode 100644
index 000000000..d28f2887e
--- /dev/null
+++ b/examples/multimedia/player/player.py
@@ -0,0 +1,194 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 Multimedia player example"""
+
+import sys
+from PySide6.QtCore import QStandardPaths, Qt, Slot
+from PySide6.QtGui import QAction, QIcon, QKeySequence
+from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
+ QMainWindow, QSlider, QStyle, QToolBar)
+from PySide6.QtMultimedia import (QAudioOutput, QMediaFormat,
+ QMediaPlayer)
+from PySide6.QtMultimediaWidgets import QVideoWidget
+
+
+AVI = "video/x-msvideo" # AVI
+
+
+MP4 = 'video/mp4'
+
+
+def get_supported_mime_types():
+ result = []
+ for f in QMediaFormat().supportedFileFormats(QMediaFormat.Decode):
+ mime_type = QMediaFormat(f).mimeType()
+ result.append(mime_type.name())
+ return result
+
+
+class MainWindow(QMainWindow):
+
+ def __init__(self):
+ super().__init__()
+
+ self._playlist = [] # FIXME 6.3: Replace by QMediaPlaylist?
+ self._playlist_index = -1
+ self._audio_output = QAudioOutput()
+ self._player = QMediaPlayer()
+ self._player.setAudioOutput(self._audio_output)
+
+ self._player.errorOccurred.connect(self._player_error)
+
+ tool_bar = QToolBar()
+ self.addToolBar(tool_bar)
+
+ file_menu = self.menuBar().addMenu("&File")
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.DocumentOpen)
+ open_action = QAction(icon, "&Open...", self,
+ shortcut=QKeySequence.Open, triggered=self.open)
+ file_menu.addAction(open_action)
+ tool_bar.addAction(open_action)
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.ApplicationExit)
+ exit_action = QAction(icon, "E&xit", self,
+ shortcut="Ctrl+Q", triggered=self.close)
+ file_menu.addAction(exit_action)
+
+ play_menu = self.menuBar().addMenu("&Play")
+ style = self.style()
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart,
+ style.standardIcon(QStyle.SP_MediaPlay))
+ self._play_action = tool_bar.addAction(icon, "Play")
+ self._play_action.triggered.connect(self._player.play)
+ play_menu.addAction(self._play_action)
+
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.MediaSkipBackward,
+ style.standardIcon(QStyle.SP_MediaSkipBackward))
+ self._previous_action = tool_bar.addAction(icon, "Previous")
+ self._previous_action.triggered.connect(self.previous_clicked)
+ play_menu.addAction(self._previous_action)
+
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackPause,
+ style.standardIcon(QStyle.SP_MediaPause))
+ self._pause_action = tool_bar.addAction(icon, "Pause")
+ self._pause_action.triggered.connect(self._player.pause)
+ play_menu.addAction(self._pause_action)
+
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.MediaSkipForward,
+ style.standardIcon(QStyle.SP_MediaSkipForward))
+ self._next_action = tool_bar.addAction(icon, "Next")
+ self._next_action.triggered.connect(self.next_clicked)
+ play_menu.addAction(self._next_action)
+
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStop,
+ style.standardIcon(QStyle.SP_MediaStop))
+ self._stop_action = tool_bar.addAction(icon, "Stop")
+ self._stop_action.triggered.connect(self._ensure_stopped)
+ play_menu.addAction(self._stop_action)
+
+ self._volume_slider = QSlider()
+ self._volume_slider.setOrientation(Qt.Horizontal)
+ self._volume_slider.setMinimum(0)
+ self._volume_slider.setMaximum(100)
+ available_width = self.screen().availableGeometry().width()
+ self._volume_slider.setFixedWidth(available_width / 10)
+ self._volume_slider.setValue(self._audio_output.volume())
+ self._volume_slider.setTickInterval(10)
+ self._volume_slider.setTickPosition(QSlider.TicksBelow)
+ self._volume_slider.setToolTip("Volume")
+ self._volume_slider.valueChanged.connect(self._audio_output.setVolume)
+ tool_bar.addWidget(self._volume_slider)
+
+ icon = QIcon.fromTheme(QIcon.ThemeIcon.HelpAbout)
+ about_menu = self.menuBar().addMenu("&About")
+ about_qt_act = QAction(icon, "About &Qt", self, triggered=qApp.aboutQt) # noqa: F821
+ about_menu.addAction(about_qt_act)
+
+ self._video_widget = QVideoWidget()
+ self.setCentralWidget(self._video_widget)
+ self._player.playbackStateChanged.connect(self.update_buttons)
+ self._player.setVideoOutput(self._video_widget)
+
+ self.update_buttons(self._player.playbackState())
+ self._mime_types = []
+
+ def closeEvent(self, event):
+ self._ensure_stopped()
+ event.accept()
+
+ @Slot()
+ def open(self):
+ self._ensure_stopped()
+ file_dialog = QFileDialog(self)
+
+ is_windows = sys.platform == 'win32'
+ if not self._mime_types:
+ self._mime_types = get_supported_mime_types()
+ if (is_windows and AVI not in self._mime_types):
+ self._mime_types.append(AVI)
+ elif MP4 not in self._mime_types:
+ self._mime_types.append(MP4)
+
+ file_dialog.setMimeTypeFilters(self._mime_types)
+
+ default_mimetype = AVI if is_windows else MP4
+ if default_mimetype in self._mime_types:
+ file_dialog.selectMimeTypeFilter(default_mimetype)
+
+ movies_location = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation)
+ file_dialog.setDirectory(movies_location)
+ if file_dialog.exec() == QDialog.Accepted:
+ url = file_dialog.selectedUrls()[0]
+ self._playlist.append(url)
+ self._playlist_index = len(self._playlist) - 1
+ self._player.setSource(url)
+ self._player.play()
+
+ @Slot()
+ def _ensure_stopped(self):
+ if self._player.playbackState() != QMediaPlayer.StoppedState:
+ self._player.stop()
+
+ @Slot()
+ def previous_clicked(self):
+ # Go to previous track if we are within the first 5 seconds of playback
+ # Otherwise, seek to the beginning.
+ if self._player.position() <= 5000 and self._playlist_index > 0:
+ self._playlist_index -= 1
+ self._playlist.previous()
+ self._player.setSource(self._playlist[self._playlist_index])
+ else:
+ self._player.setPosition(0)
+
+ @Slot()
+ def next_clicked(self):
+ if self._playlist_index < len(self._playlist) - 1:
+ self._playlist_index += 1
+ self._player.setSource(self._playlist[self._playlist_index])
+
+ @Slot("QMediaPlayer::PlaybackState")
+ def update_buttons(self, state):
+ media_count = len(self._playlist)
+ self._play_action.setEnabled(media_count > 0 and state != QMediaPlayer.PlayingState)
+ self._pause_action.setEnabled(state == QMediaPlayer.PlayingState)
+ self._stop_action.setEnabled(state != QMediaPlayer.StoppedState)
+ self._previous_action.setEnabled(self._player.position() > 0)
+ self._next_action.setEnabled(media_count > 1)
+
+ def show_status_message(self, message):
+ self.statusBar().showMessage(message, 5000)
+
+ @Slot("QMediaPlayer::Error", str)
+ def _player_error(self, error, error_string):
+ print(error_string, file=sys.stderr)
+ self.show_status_message(error_string)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ main_win = MainWindow()
+ available_geometry = main_win.screen().availableGeometry()
+ main_win.resize(available_geometry.width() / 3,
+ available_geometry.height() / 2)
+ main_win.show()
+ sys.exit(app.exec())