ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 885
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Глава 28. Мультимедиа
685 ния (листинг 28.3) — добавленные и исправленные строки выделены здесь полужирным шрифтом.
Листинг 28.3. Простейший видеопроигрыватель from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets class MyWindow(QtWidgets.QWidget): def __init__(self, parent = None): self.setWindowTitle("Видеопроигрыватель") vbox.addWidget(btnOpen) vwg = QtMultimediaWidgets.QVideoWidget() vwg.setAspectRatioMode(QtCore.Qt.KeepAspectRatio) self.mplPlayer.setVideoOutput(vwg) vbox.addWidget(vwg) self.sldPosition = QtWidgets.QSlider(QtCore.Qt.Horizontal) self.setLayout(vbox) self.resize(300, 300) def openFile(self): file = QtWidgets.QFileDialog.getOpenFileUrl(parent=self, caption = "Выберите видеофайл", filter = "Видеофайлы (*.avi *.mp4)") self.mplPlayer.setMedia(QtMultimedia.QMediaContent(file[0]))
Рис. 28.3. Простейший видеопроигрыватель
686
Часть II. Библиотека PyQt 5 28.3. Класс QMediaPlaylist
Класс
QMediaPlaylist реализует поддержку списков воспроизведения (плейлистов). Уста- новить плейлист в качестве источника мультимедийных данных позволяет метод setPlaylist()
класса
QMediaPlayer
Иерархия наследования класса
QMediaPlaylist выглядит так:
(QObject, QMediaBindableInterface) — QMediaPlaylist
А формат вызова его конструктора таков:
<Объект> = QMediaPlaylist([parent=None])
В параметре parent может быть указана ссылка на родительский компонент.
Класс
QMediaPlaylist поддерживает следующие основные методы (полный их список мож- но найти на странице https://doc.qt.io/qt-5/qmediaplaylist.html):
addMedia()
— добавляет указанный источник или источники в конец плейлиста и воз- вращает
True
, если добавление прошло успешно, и
False
— в противном случае. Форма- ты метода: addMedia(
insertMedia()
— вставляет указанный источник или источники в позицию плейлиста, обозначенную заданным индексом, и возвращает
True
, если вставка прошла успешно, и
False
— в противном случае. Форматы метода: insertMedia(<Индекс>,
moveMedia(<Индекс 1>, <Индекс 2>)
— перемещает позицию, обозначенную
<Индексом
1>
, в местоположение, обозначенное
<Индексом 2>
. Возвращает
True
, если перемещение удалось, и
False
— в противном случае. Поддерживается, начиная с PyQt 5.7;
removeMedia(<Индекс>)
— удаляет обозначенную индексом позицию из плейлиста и воз- вращает
True
, если удаление прошло успешно, и
False
— в противном случае;
removeMedia(<Начальный индекс>, <Конечный индекс>)
— удаляет из плейлиста позиции, находящиеся между указанными индексами (позиция, обозначенная конечным индек- сом, не удаляется). Возвращает
True
, если удаление прошло успешно, и
False
— в про- тивном случае;
clear()
— удаляет все позиции из плейлиста. Возвращает
True
, если удаление прошло успешно, и
False
— в противном случае;
isReadOnly()
— возвращает
True
, если содержимое плейлиста не может быть изменено, и
False
— в противном случае;
setPlaybackMode(<Порядок воспроизведения>)
— задает порядок воспроизведения пози- ций. В качестве параметра указывается значение одного из следующих атрибутов класса
QMediaPlaylist
:
•
CurrentItemOnce
—
0
— текущая позиция воспроизводится однократно;
•
CurrentItemInLoop
—
1
— текущая позиция воспроизводится снова и снова;
•
Sequential
—
2
— содержимое плейлиста воспроизводится до самого конца одно- кратно, начиная с текущей позиции;
Глава 28. Мультимедиа
687
•
Loop
—
3
— содержимое плейлиста воспроизводится до самого конца снова и снова;
•
Random
—
4
— позиции плейлиста воспроизводятся в случайном порядке;
mediaCount()
— возвращает количество позиций в плейлисте;
isEmpty()
— возвращает
True
, если плейлист пуст, и
False
— в противном случае;
media(<Индекс>)
— возвращает позицию (экземпляр класса
QMediaContent
), соответст- вующую указанному индексу, или
None
, если такой позиции нет;
setCurrentIndex(<Индекс>)
— начинает воспроизведение позиции с указанным индек- сом. Метод является слотом;
currentIndex()
— возвращает индекс текущей позиции (воспроизводящейся в настоя- щий момент);
currentMedia()
— возвращает текущую позицию в виде экземпляра класса
QMediaContent
;
previousIndex([steps=1])
— возвращает индекс позиции, отстоящей на текущей на за- данное параметром steps число позиций, считая в направлении к началу плейлиста;
nextIndex([steps=1])
— возвращает индекс позиции, отстоящей на текущей на заданное параметром steps число позиций, считая в направлении к концу плейлиста;
previous()
— начинает воспроизведение предыдущей позиции в плейлисте. Метод является слотом;
next()
— начинает воспроизведение следующей позиции в плейлисте. Метод является слотом;
shuffle()
— упорядочивает позиции плейлиста случайным образом. Метод является слотом;
load(
— загружает плейлист из файла, заданного первым парамет- ром. Содержимое загруженного плейлиста добавляется в конец текущего. Во втором параметре можно указать формат загружаемого плейлиста — если он не указан, формат будет определен по расширению файла.
Из информации, собранной в Интернете, авторам удалось выяснить список поддержи- ваемых форматов плейлистов: M3U (формат плейлиста Winamp) и M3U8 (формат плей- листа Winamp с поддержкой UTF-8). Обозначение формата указывается во втором пара- метре в виде строки, набранной только строчными буквами: m3u или m3u8
: mpl = QtMultimedia.QMediaPlaylist() file = QtCore.QUrl.fromLocalFile(r"c:\media\playlist.m3u8") mpl.load(file) player.setPlaylist(mpl)
save(
— сохраняет плейлист в файле, заданном первым парамет- ром. Возвращает
True
, если сохранение прошло успешно, и
False
— в противном случае.
Во втором параметре указывается формат сохраняемого плейлиста в виде строки m3u или m3u8
: file = QtCore.QUrl.fromLocalFile(r"c:\media\playlist.m3u8") mpl.save(file, "m3u8")
В
НИМАНИЕ
!
Метод save() даже при указании формата m3u8 сохраняет плейлист в кодировке Windows-
1251, а не в UTF-8, причем пути к файлам записываются в виде URL. Вероятно, это ошибка в библиотеке PyQt. Поэтому для сохранения плейлистов рекомендуется использовать ин- струменты Python, обеспечивающие работу с файлами (см. главу 16).
688
Часть II. Библиотека PyQt 5
error()
— возвращает ошибку, возникшую при обработке плейлиста, в виде значения одного из следующих атрибутов класса
QMediaPlaylist
:
•
NoError
—
0
— никакой ошибки не возникло;
•
FormatError
—
1
— файл плейлиста поврежден, или это вообще не плейлист;
•
FormatNotSupportedError
—
2
— неподдерживаемый формат плейлиста;
•
NetworkError
—
3
— сетевая ошибка;
•
AccessDeniedError
—
4
— недостаточно прав для загрузки плейлиста;
errorString()
— возвращает текстовое описание ошибки;
mediaObject()
— возвращает ссылку (экземпляр класса
QMediaObject
) на мультимедий- ный проигрыватель, воспроизводящий этот плейлист, или
None
, если плейлист не вос- производится ни в каком проигрывателе.
Класс
QMediaPlaylist поддерживает большое количество сигналов, из которых для нас представляют интерес лишь приведенные далее (полный их список можно найти на страни- це https://doc.qt.io/qt-5/qmediaplaylist.html).
currentIndexChanged(<Индекс>)
— генерируется при смене текущей позиции плейлиста.
В параметре передается целочисленный индекс новой позиции;
currentMediaChanged(
— генерируется при смене текущей позиции плейлиста. В параметре передается сама новая позиция;
loaded()
— генерируется после успешной загрузки плейлиста;
loadFailed()
— генерируется, если в процессе загрузки плейлиста возникла ошибка.
Для примера напишем совсем простое приложение аудиопроигрывателя, воспроизводящего плейлист (листинг 28.4). Оно будет создавать плейлист из четырех аудиофайлов, находя- щихся в той же папке, что и само приложение, воспроизводить его и позволит пользователю переключаться на предыдущую и следующую позицию плейлиста.
Листинг 28.4. Использование плейлистов from PyQt5 import QtCore, QtWidgets, QtMultimedia import sys, os 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.playlist = QtMultimedia.QMediaPlaylist() files = ["audio1.mp3", "audio2.mp3", "audio3.mp3", "audio4.mp3"] for f in files: fn = QtCore.QUrl.fromLocalFile(os.path.abspath(f)) self.playlist.addMedia(QtMultimedia.QMediaContent(fn))
# Поэкспериментируем со вставкой и удалением позиций в плейлисте
# Вставляем вторую позицию в конец плейлиста self.playlist.insertMedia(4, self.playlist.media(1))
Глава 28. Мультимедиа
689
# Удаляем вторую позицию self.playlist.removeMedia(1) self.playlist.setCurrentIndex(0) self.mplPlayer.setPlaylist(self.playlist)
# Создаем элементы управления воспроизведением vbox = QtWidgets.QVBoxLayout() hbox = QtWidgets.QHBoxLayout() self.btnPlay = QtWidgets.QPushButton("&Пуск") self.btnPlay.clicked.connect(self.mplPlayer.play) hbox.addWidget(self.btnPlay) self.btnNext = QtWidgets.QPushButton("П&редыдущая") self.btnNext.clicked.connect(self.playlist.previous) hbox.addWidget(self.btnNext) self.btnPrevious = QtWidgets.QPushButton("&Следующая") self.btnPrevious.clicked.connect(self.playlist.next) hbox.addWidget(self.btnPrevious) vbox.addLayout(hbox) self.lblCurrent = QtWidgets.QLabel("") vbox.addWidget(self.lblCurrent) self.playlist.currentMediaChanged.connect(self.showFile) self.setLayout(vbox) self.resize(300, 70)
# Выводим на экран имя файла, воспроизводящегося в данный момент
# Метод canonicalUrl() класса QMediaContent возвращает
# путь к файлу экземпляра класса QUrl, а метод fileName()
# класса QUrl позволяет узнать имя файла def showFile(self, content): self.lblCurrent.setText(content.canonicalUrl().fileName()) app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_())
28.4. Запись звука
Библиотека PyQt 5 предоставляет довольно богатые возможности записи звука и сохране- ния его в файле. Сейчас мы выясним, как это делается.
П
РИМЕЧАНИЕ
Помимо записи звука, PyQt 5 также позволяет с применением подключенной к компьютеру камеры производить фото- и видеосъемку. Как это выполняется, описано в документации по библиотеке.
28.4.1. Класс QAudioRecorder
Класс
QAudioRecorder позволяет записывать звук с микрофона и сохранять его в аудиофайле в закодированном виде. Его иерархия наследования выглядит так:
(QObject, QMediaBindableInterface) — QMediaRecorder - QAudioRecorder
690
Часть II. Библиотека PyQt 5
Формат вызова конструктора этого класса следующий:
<Объект> = QAudioRecorder([parent=None])
В параметре parent может быть указана ссылка на родительский компонент.
Бо´льшую часть полезных для нас методов
QAudioRecorder наследует от базового класса —
QMediaRecorder
. Эти методы приведены далее (полный их список можно найти на страницах https://doc.qt.io/qt-5/qmediarecorder.html и https://doc.qt.io/qt-5/qaudiorecorder.html).
setOutputLocation(
— задает путь к файлу, в котором будет сохраняться запи- сываемый звук;
setAudioInput(<Звуковой вход>)
— задает вход, с которого будет сниматься записывае- мый звук. Наименование входа задается в виде строки;
setContainerFormat(<Формат файла>)
— задает MIME-тип файла, в котором будет со- храняться записываемый звук. Формат указывается в виде строки;
setAudioSettings(
— задает параметры кодирования записы- ваемого звука. Параметры указываются в виде экземпляра класса
QAudioEncoderSettings
;
setVolume(<Уровень>)
— задает уровень записываемого звука в виде числа от
0
(звук отключен) до
100
(максимальный уровень). Метод является слотом;
record()
— запускает или возобновляет запись звука. Метод является слотом;
pause()
— приостанавливает запись звука. Метод является слотом;
stop()
— останавливает запись звука. Метод является слотом;
setMetaData(<Ключ>, <Значение>)
— заносит в метаданные сохраняемого файла задан- ное значение под заданным ключом. Доступные ключи были рассмотрены в описании метода metaData()
(см. разд. 28.1);
defaultAudioInput()
— возвращает строку с наименованием звукового входа, исполь- зуемого по умолчанию: ar = QtMultimedia.QAudioRecorder() print(ar.defaultAudioInput())
У авторов вывел:
Default Input Device
audioInputs()
— возвращает список наименований всех имеющихся в системе звуковых входов, заданных строками: for f in ar.audioInputs(): print(f)
У авторов вывел:
Микрофон (VIA HD Audio)
Analog Mix (Line/CD/Aux/TAD/PC) (Creative SB Audigy)
Microphone (Creative SB Audigy)
Остальное пропущено;
supportedContainers()
— возвращает список всех поддерживаемых классом
QAudioRecorder
MIME-типов файлов, указанных в виде строк: for f in ar.supportedContainers(): print(f, end = " ")
Выведет: audio/x-wav audio/x-raw
Как видим, поддерживаются лишь форматы WAV и RAW;
1 ... 61 62 63 64 65 66 67 68 ... 83
Глава 28. Мультимедиа
691
supportedAudioCodecs()
— выводит список наименований всех поддерживаемых клас- сом
QAudioRecorder аудиокодеков, заданных в виде строк: for f in ar.supportedAudioCodecs(): print(f, end = " ")
Выведет: audio/pcm
Как можно видеть, поддерживается лишь кодек PCM — самый простой из имеющих хо- ждение;
supportedAudioSampleRates([settings=QAudioEncoderSettings()])
— позволяет узнать поддерживаемые частоты дискретизации звука. Если в параметре settings указать экземпляр класса
QAudioEncoderSettings
, задающий параметры кодирования, будут воз- вращены только частоты, доступные для этих параметров.
Возвращаемый результат представляет собой кортеж, первый элемент которого — спи- сок целочисленных значений частот дискретизации. Второй элемент будет значением
True
, если поддерживаются произвольные частоты дискретизации, или
False
— в про- тивном случае: sr = ar.supportedAudioSampleRates() for f in sr[0]: print(f, end = " ") print() print(sr[1])
Выведет:
# 8000 11025 16000 22050 32000 44100 48000 88200 96000 192000
# False
duration()
— возвращает текущую продолжительность записанного звука в миллисе- кундах;
volume()
— возвращает уровень записываемого звука в виде числа от
0
до
100
;
state()
— возвращает текущее состояние записи звука в виде значения одного из сле- дующих атрибутов класса
QMediaRecorder
:
•
StoppedState
—
0
— запись звука не начиналась или была остановлена;
•
RecordingState
—
1
— идет запись звука;
•
PausedState
—
2
— запись звука приостановлена;
status()
— возвращает текущее состояние подсистемы записи звука в виде значения одного из следующих атрибутов класса
QMediaRecorder
:
•
UnavailableStatus
—
0
— состояние определить не удается, подсистема записи звука недоступна, или указаны не поддерживаемые параметры записи;
•
UnloadedStatus
—
1
— подсистема записи звука неактивна;
•
LoadingStatus
—
2
— подсистема записи звука в настоящий момент активизируется;
•
LoadedStatus
—
3
— подсистема записи звука активна;
•
StartingStatus
—
4
— запускается запись звука;
•
RecordingStatus
—
5
— идет запись звука;
•
PausedStatus
—
6
— запись звука приостановлена;
•
FinalizingStatus
—
7
— запись звука остановлена, и идет сохранение аудиофайла;
692
Часть II. Библиотека PyQt 5
error()
— возвращает ошибку, возникшую при записи звука, в виде значения одного из следующих атрибутов класса
QMediaRecorder
:
•
NoError
—
0
— никакой ошибки не возникло;
•
ResourceError
—
1
— подсистема записи звука недоступна или не готова к работе;
•
FormatError
—
2
— заданы недопустимые параметры кодирования звука;
•
OutOfSpaceError
—
3
— недостаточно места для сохранения аудиофайла;
errorString()
— возвращает текстовое описание ошибки.
Класс
QAudioRecorder поддерживает довольно много сигналов, из которых нас интересуют лишь некоторые (полный их список можно найти на страницах https://doc.qt.io/qt-5/ qmediarecorder.html и https://doc.qt.io/qt-5/qaudiorecorder.html):
durationChanged(<Продолжительность>)
— генерируется при изменении продолжитель- ности записанного звука. В параметре передается новое значение продолжительности, заданное целым числом;
stateChanged(<Состояние>)
— генерируется при изменении состояния записи звука.
В параметре передается целочисленный идентификатор нового состояния;
statusChanged(<Состояние>)
— генерируется при изменении состояния подсистемы записи звука. В параметре передается целочисленный идентификатор нового состояния;
volumeChanged(<Уровень звука>)
— генерируется при изменении уровня записываемого звука. В параметре передается новое значение уровня в виде целого числа.
28.4.2. Класс QAudioEncoderSettings
Класс
QAudioEncoderSettings используется для настройки параметров кодирования записы- ваемого звука. Формат вызова его конструктора очень прост:
<Объект> = QAudioEncoderSettings([
Если указать в качестве параметра экземпляр класса
QAudioEncoderSettings
, будет создана его копия.
Класс
QAudioEncoderSettings поддерживает следующие основные методы (полный их спи- сок можно найти на странице https://doc.qt.io/qt-5/qaudioencodersettings.html):
setCodec(<Кодек>)
— задает наименование используемого аудиокодека, указываемое в виде строки;
setSampleRate(<Частота дискретизации>)
— задает частоту дискретизации кодируемого звука, выраженную в герцах. Если указать значение
-1
, PyQt сама выберет оптимальную частоту дискретизации, исходя из возможностей звукового входа и выбранного кодека;
setChannelCount(<Количество каналов>)
— задает количество каналов кодируемого зву- ка. Если указать значение
-1
, PyQt сама выберет оптимальное количество каналов, исхо- дя из возможностей звукового входа и выбранного кодека;
setEncodingMode(<Режим кодирования>)
— задает режим кодирования звука. В качестве параметра указывается значение одного из следующих атрибутов класса
QMultimedia
:
•
ConstantQualityEncoding
—
0
— режим кодирования с постоянным качеством. Каче- ство задается методом setQuality()
, а подходящий битрейт подбирается самой PyQt;