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.py99
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)