Шаг 290.
Библиотека PyQt5.
Мультимедиа. Класс QMediaPlayer (окончание)

    На этом шаге мы перечислим поддерживаемые сигналы и проведем два примера, иллюстрирующих использование этого класса.

    Класс QMediaPlayer поддерживает большое количество сигналов, из которых для нас представляют интерес лишь приведенные далее (полный их список доступен на странице https://doc.qt.io/qt-5/qmediaplayer.html):

    Простейший аудиопроигрыватель (его код приведен ниже) содержит кнопку для открытия звукового файла, кнопки пуска, паузы и остановки воспроизведения, регулятор текущей позиции воспроизведения, регулятор громкости и кнопку временного отключения звука (рисунок 1).

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtWidgets, QtMultimedia
import sys

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent,
                    flags=QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint)
        self.setWindowTitle("Аудиопроигрыватель")
        # Создаем сам проигрыватель
        self.mplPlayer = QtMultimedia.QMediaPlayer()
        self.mplPlayer.setVolume(50)
        self.mplPlayer.mediaStatusChanged.connect(self.initPlayer)
        self.mplPlayer.stateChanged.connect(self.setPlayerState)
        vbox = QtWidgets.QVBoxLayout()
        # Создаем кнопку открытия файла
        btnOpen = QtWidgets.QPushButton("&Открыть файл...")
        btnOpen.clicked.connect(self.openFile)
        vbox.addWidget(btnOpen)
        # Создаем компоненты для управления воспроизведением.
        # Делаем их изначально недоступными
        self.sldPosition = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.sldPosition.setMinimum(0)
        self.sldPosition.valueChanged.connect(self.mplPlayer.setPosition)
        self.mplPlayer.positionChanged.connect(self.sldPosition.setValue)
        self.sldPosition.setEnabled(False)
        vbox.addWidget(self.sldPosition)
        hbox = QtWidgets.QHBoxLayout()
        self.btnPlay = QtWidgets.QPushButton("&Пуск")
        self.btnPlay.clicked.connect(self.mplPlayer.play)
        self.btnPlay.setEnabled(False)
        hbox.addWidget(self.btnPlay)
        self.btnPause = QtWidgets.QPushButton("П&ауза")
        self.btnPause.clicked.connect(self.mplPlayer.pause)
        self.btnPause.setEnabled(False)
        hbox.addWidget(self.btnPause)
        self.btnStop = QtWidgets.QPushButton("&Стоп")
        self.btnStop.clicked.connect(self.mplPlayer.stop)
        self.btnStop.setEnabled(False)
        hbox.addWidget(self.btnStop)
        vbox.addLayout(hbox)
        # Создаем компоненты для управления громкостью
        hbox = QtWidgets.QHBoxLayout()
        lblVolume = QtWidgets.QLabel("&Громкость")
        hbox.addWidget(lblVolume)
        sldVolume = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        sldVolume.setRange(0, 100)
        sldVolume.setTickPosition(QtWidgets.QSlider.TicksAbove)
        sldVolume.setTickInterval(10)
        sldVolume.setValue(50)
        lblVolume.setBuddy(sldVolume)
        sldVolume.valueChanged.connect(self.mplPlayer.setVolume)
        hbox.addWidget(sldVolume)
        btnMute = QtWidgets.QPushButton("&Тихо!")
        btnMute.setCheckable(True)
        btnMute.toggled.connect(self.mplPlayer.setMuted)
        hbox.addWidget(btnMute)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.resize(300, 100)

    # Для открытия файла используем метод getOpenFileUrl() класса
    # QFileDialog, т. к. для создания экземпляра класса
    # QMediaContent нам нужен путь к файлу, заданный в виде
    # экземпляра класса QUrl
    def openFile(self):
        file = QtWidgets.QFileDialog.getOpenFileUrl(parent=self,
                caption="Выберите звуковой файл",
                filter="Звуковые файлы (*.mp3 *.ac3)")
        self.mplPlayer.setMedia(QtMultimedia.QMediaContent(file[0]))

    def initPlayer(self, state):
        if state == QtMultimedia.QMediaPlayer.LoadedMedia:
            # После загрузки файла подготавливаем проигрыватель
            # для его воспроизведения
            self.mplPlayer.stop()
            self.btnPlay.setEnabled(True)
            self.sldPosition.setEnabled(True)
            self.sldPosition.setMaximum(self.mplPlayer.duration())
        elif state == QtMultimedia.QMediaPlayer.EndOfMedia:
            # По окончании воспроизведения файла возвращаем
            # проигрыватель в изначальное состояние
            self.mplPlayer.stop()
        elif state == QtMultimedia.QMediaPlayer.NoMedia or 
               state == QtMultimedia.QMediaPlayer.InvalidMedia:
            # Если файл не был загружен, отключаем компоненты,
            # управляющие воспроизведением
            self.sldPosition.setValue(0)
            self.sldPosition.setEnabled(False)
            self.btnPlay.setEnabled(False)
            self.btnPause.setEnabled(False)
            self.btnStop.setEnabled(False)

    # В зависимости от того, воспроизводится ли файл, поставлен
    # ли он на паузу или остановлен, делаем соответствующие кнопки
    # доступными или недоступными
    def setPlayerState(self, state):
        if state == QtMultimedia.QMediaPlayer.StoppedState:
            self.sldPosition.setValue(0)
            self.btnPause.setEnabled(False)
            self.btnStop.setEnabled(False)
        elif state == QtMultimedia.QMediaPlayer.PlayingState:
            self.btnPause.setEnabled(True)
            self.btnStop.setEnabled(True)
        elif state == QtMultimedia.QMediaPlayer.PausedState:
            self.btnPause.setEnabled(False)
            self.btnStop.setEnabled(True)

app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
Архив с файлом можно взять здесь.

    Результат работы приложения показан на рисунке 1.


Рис.1. Интерфейс простейшего аудиопроигрывателя

    В следующем примере приведен код служебной утилиты, выводящей метаданные, которые хранятся в загруженном мультимедийном файле. В настоящий момент она выводит сведения об открытом в ней аудиофайле (рисунок 2).

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtWidgets, QtMultimedia
import sys

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent, flags =
                        QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint)
        self.setWindowTitle("Метаданные")
        self.mplPlayer = QtMultimedia.QMediaPlayer()
        self.mplPlayer.setVolume(50)
        self.mplPlayer.mediaStatusChanged.connect(self.showMetadata)
        vbox = QtWidgets.QVBoxLayout()
        btnOpen = QtWidgets.QPushButton("&Открыть файл...")
        btnOpen.clicked.connect(self.openFile)
        vbox.addWidget(btnOpen)
        #  Создаем доступное только для чтения многострочное текстовое
        # поле, в которое будет выводиться результат
        self.txtOutput = QtWidgets.QTextEdit()
        self.txtOutput.setReadOnly(True)
        vbox.addWidget(self.txtOutput)
        self.setLayout(vbox)
        self.resize(300, 300)

    def openFile(self):
        file = QtWidgets.QFileDialog.getOpenFileUrl(parent=self,
                    caption = "Выберите звуковой файл",
                    filter = "Звуковые файлы (*.mp3 *.ac3)")
        self.mplPlayer.setMedia(QtMultimedia.QMediaContent(file[0]))

    def showMetadata(self, state):
        self.txtOutput.clear()
        # Как только файл будет загружен...
        if state == QtMultimedia.QMediaPlayer.LoadedMedia:
            # ...извлекаем ключи всех доступных метаданных...
            keys = self.mplPlayer.availableMetaData()
            s = ""
            # ...перебираем их в цикле...
            for k in keys:
                v = self.mplPlayer.metaData(k)
                # ... на случай пустых списков проверяем, действительно
                # ли по этому ключу хранится какое-то значение...
                if v:
                    # ...если значение представляет собой список,
                    # преобразуем его в строку...
                    if v is list:
                        v = ", ".join(v)
                    # ...формируем на основе значений текст...
                    s += "<strong>" + k + "</strong>: " + str(v) + "<br>"
                    # ...и выводим его в текстовое поле
                    self.txtOutput.setHtml(s)

app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
Архив с файлом можно взять здесь.

    Результат работы приложения показан на рисунке 2.


Рис.2. Интерфейс утилиты, выводящей метаданные мультимедийного файла

    На следующем шаге мы рассмотрим класс QVideoWidget.




Предыдущий шаг Содержание Следующий шаг