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.py249
1 files changed, 155 insertions, 94 deletions
diff --git a/examples/multimedia/player/player.py b/examples/multimedia/player/player.py
index 44df8853b..359c4ec3d 100644
--- a/examples/multimedia/player/player.py
+++ b/examples/multimedia/player/player.py
@@ -1,7 +1,7 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -42,118 +42,179 @@
"""PySide6 Multimedia player example"""
import sys
-from PySide6.QtCore import QStandardPaths, Qt
+from PySide6.QtCore import QStandardPaths, Qt, Slot
from PySide6.QtGui import QAction, QIcon, QKeySequence, QScreen
from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
QMainWindow, QSlider, QStyle, QToolBar)
-from PySide6.QtMultimedia import QMediaPlayer, QMediaPlaylist
+from PySide6.QtMultimedia import QMediaFormat, QMediaPlayer, QMediaPlaylist
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 = QMediaPlaylist()
- self.player = QMediaPlayer()
-
- toolBar = QToolBar()
- self.addToolBar(toolBar)
-
- fileMenu = self.menuBar().addMenu("&File")
- openAction = QAction(QIcon.fromTheme("document-open"),
- "&Open...", self, shortcut=QKeySequence.Open,
- triggered=self.open)
- fileMenu.addAction(openAction)
- exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit",
- self, shortcut="Ctrl+Q", triggered=self.close)
- fileMenu.addAction(exitAction)
-
- playMenu = self.menuBar().addMenu("&Play")
- playIcon = self.style().standardIcon(QStyle.SP_MediaPlay)
- self.playAction = toolBar.addAction(playIcon, "Play")
- self.playAction.triggered.connect(self.player.play)
- playMenu.addAction(self.playAction)
-
- previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward)
- self.previousAction = toolBar.addAction(previousIcon, "Previous")
- self.previousAction.triggered.connect(self.previousClicked)
- playMenu.addAction(self.previousAction)
-
- pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause)
- self.pauseAction = toolBar.addAction(pauseIcon, "Pause")
- self.pauseAction.triggered.connect(self.player.pause)
- playMenu.addAction(self.pauseAction)
-
- nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward)
- self.nextAction = toolBar.addAction(nextIcon, "Next")
- self.nextAction.triggered.connect(self.playlist.next)
- playMenu.addAction(self.nextAction)
-
- stopIcon = self.style().standardIcon(QStyle.SP_MediaStop)
- self.stopAction = toolBar.addAction(stopIcon, "Stop")
- self.stopAction.triggered.connect(self.player.stop)
- playMenu.addAction(self.stopAction)
-
- self.volumeSlider = QSlider()
- self.volumeSlider.setOrientation(Qt.Horizontal)
- self.volumeSlider.setMinimum(0)
- self.volumeSlider.setMaximum(100)
- self.volumeSlider.setFixedWidth(self.screen().availableGeometry().width() / 10)
- self.volumeSlider.setValue(self.player.volume())
- self.volumeSlider.setTickInterval(10)
- self.volumeSlider.setTickPosition(QSlider.TicksBelow)
- self.volumeSlider.setToolTip("Volume")
- self.volumeSlider.valueChanged.connect(self.player.setVolume)
- toolBar.addWidget(self.volumeSlider)
-
- aboutMenu = self.menuBar().addMenu("&About")
- aboutQtAct = QAction("About &Qt", self, triggered=qApp.aboutQt)
- aboutMenu.addAction(aboutQtAct)
-
- self.videoWidget = QVideoWidget()
- self.setCentralWidget(self.videoWidget)
- self.player.setPlaylist(self.playlist)
- self.player.stateChanged.connect(self.updateButtons)
- self.player.setVideoOutput(self.videoWidget)
-
- self.updateButtons(self.player.state())
-
+ self._playlist = QMediaPlaylist()
+ self._player = QMediaPlayer()
+ self._player.errorOccurred.connect(self._player_error)
+
+ tool_bar = QToolBar()
+ self.addToolBar(tool_bar)
+
+ file_menu = self.menuBar().addMenu("&File")
+ icon = QIcon.fromTheme("document-open")
+ open_action = QAction(icon, "&Open...", self,
+ shortcut=QKeySequence.Open, triggered=self.open)
+ file_menu.addAction(open_action)
+ icon = QIcon.fromTheme("application-exit")
+ 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("media-playback-start.png",
+ 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("media-skip-backward-symbolic.svg",
+ 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("media-playback-pause.png",
+ 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("media-skip-forward-symbolic.svg",
+ 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("media-playback-stop.png",
+ 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._player.volume())
+ self._volume_slider.setTickInterval(10)
+ self._volume_slider.setTickPosition(QSlider.TicksBelow)
+ self._volume_slider.setToolTip("Volume")
+ self._volume_slider.valueChanged.connect(self._player.setVolume)
+ tool_bar.addWidget(self._volume_slider)
+
+ about_menu = self.menuBar().addMenu("&About")
+ about_qt_act = QAction("About &Qt", self, triggered=qApp.aboutQt)
+ 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):
- fileDialog = QFileDialog(self)
- supportedMimeTypes = QMediaPlayer.supportedMimeTypes()
- if not supportedMimeTypes:
- supportedMimeTypes.append("video/x-msvideo") # AVI
- fileDialog.setMimeTypeFilters(supportedMimeTypes)
- moviesLocation = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation)
- fileDialog.setDirectory(moviesLocation)
- if fileDialog.exec() == QDialog.Accepted:
- self.playlist.addMedia(fileDialog.selectedUrls()[0])
- self.player.play()
-
- def previousClicked(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)
+
+ 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.addMedia(url)
+ 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:
- self.playlist.previous()
+ if self._player.position() <= 5000:
+ self._playlist.previous()
+ self._player.setSource(self._playlist.currentMedia())
else:
- self.player.setPosition(0)
+ self._player.setPosition(0)
+
+ @Slot()
+ def next_clicked(self):
+ self._playlist.next()
+ self._player.setSource(self._playlist.currentMedia())
- def updateButtons(self, state):
- mediaCount = self.playlist.mediaCount()
- self.playAction.setEnabled(mediaCount > 0
+ def update_buttons(self, state):
+ media_count = self._playlist.mediaCount()
+ self._play_action.setEnabled(media_count > 0
and state != QMediaPlayer.PlayingState)
- self.pauseAction.setEnabled(state == QMediaPlayer.PlayingState)
- self.stopAction.setEnabled(state != QMediaPlayer.StoppedState)
- self.previousAction.setEnabled(self.player.position() > 0)
- self.nextAction.setEnabled(mediaCount > 1)
+ 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)
- mainWin = MainWindow()
- availableGeometry = mainWin.screen().availableGeometry()
- mainWin.resize(availableGeometry.width() / 3, availableGeometry.height() / 2)
- mainWin.show()
+ 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())