diff options
Diffstat (limited to 'examples/multimedia/player/player.py')
-rw-r--r-- | examples/multimedia/player/player.py | 99 |
1 files changed, 36 insertions, 63 deletions
diff --git a/examples/multimedia/player/player.py b/examples/multimedia/player/player.py index 5aa31c5bd..d28f2887e 100644 --- a/examples/multimedia/player/player.py +++ b/examples/multimedia/player/player.py @@ -1,52 +1,15 @@ - -############################################################################# -## -## 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. -## -## $QT_BEGIN_LICENSE:BSD$ -## You may use this file under the terms of the BSD license as follows: -## -## "Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are -## met: -## * Redistributions of source code must retain the above copyright -## notice, this list of conditions and the following disclaimer. -## * Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in -## the documentation and/or other materials provided with the -## distribution. -## * Neither the name of The Qt Company Ltd nor the names of its -## contributors may be used to endorse or promote products derived -## from this software without specific prior written permission. -## -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -## -## $QT_END_LICENSE$ -## -############################################################################# +# 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, QScreen +from PySide6.QtGui import QAction, QIcon, QKeySequence from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog, - QMainWindow, QSlider, QStyle, QToolBar) -from PySide6.QtMultimedia import QMediaFormat, QMediaPlayer, QMediaPlaylist + QMainWindow, QSlider, QStyle, QToolBar) +from PySide6.QtMultimedia import (QAudioOutput, QMediaFormat, + QMediaPlayer) from PySide6.QtMultimediaWidgets import QVideoWidget @@ -69,51 +32,55 @@ class MainWindow(QMainWindow): def __init__(self): super().__init__() - self._playlist = QMediaPlaylist() + 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("document-open") + 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("application-exit") + 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("media-playback-start.png", + 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("media-skip-backward-symbolic.svg", + 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("media-playback-pause.png", + 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("media-skip-forward-symbolic.svg", + 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("media-playback-stop.png", + 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) @@ -125,15 +92,16 @@ class MainWindow(QMainWindow): 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.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._player.setVolume) + 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("About &Qt", self, triggered=qApp.aboutQt) + about_qt_act = QAction(icon, "About &Qt", self, triggered=qApp.aboutQt) # noqa: F821 about_menu.addAction(about_qt_act) self._video_widget = QVideoWidget() @@ -158,6 +126,8 @@ class MainWindow(QMainWindow): 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) @@ -169,7 +139,8 @@ class MainWindow(QMainWindow): file_dialog.setDirectory(movies_location) if file_dialog.exec() == QDialog.Accepted: url = file_dialog.selectedUrls()[0] - self._playlist.addMedia(url) + self._playlist.append(url) + self._playlist_index = len(self._playlist) - 1 self._player.setSource(url) self._player.play() @@ -182,21 +153,23 @@ class MainWindow(QMainWindow): 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: + if self._player.position() <= 5000 and self._playlist_index > 0: + self._playlist_index -= 1 self._playlist.previous() - self._player.setSource(self._playlist.currentMedia()) + self._player.setSource(self._playlist[self._playlist_index]) else: self._player.setPosition(0) @Slot() def next_clicked(self): - self._playlist.next() - self._player.setSource(self._playlist.currentMedia()) + 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 = self._playlist.mediaCount() - self._play_action.setEnabled(media_count > 0 - and state != QMediaPlayer.PlayingState) + 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) @@ -205,7 +178,7 @@ class MainWindow(QMainWindow): def show_status_message(self, message): self.statusBar().showMessage(message, 5000) - @Slot(QMediaPlayer.Error, str) + @Slot("QMediaPlayer::Error", str) def _player_error(self, error, error_string): print(error_string, file=sys.stderr) self.show_status_message(error_string) |