ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
" + k + ": " + str(v) + " " # ...и выводим его в текстовое поле self.txtOutput.setHtml(s) app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) 28.2. Класс QVideoWidget Класс QVideoWidget , определенный в модуле QtMultimediaWidgets , представляет панель вы- вода видео, которое воспроизводится мультимедийным проигрывателем. Задать панель вы- вода видео для мультимедийного проигрывателя можно вызовом метода setVideoOutput() класса QMediaPlayer Иерархия наследования класса QVideoWidget выглядит следующим образом: (QObject, QPaintDevice) — (QWidget, QMediaBindableInterface) — QVideoWidget А формат вызова его конструктора таков: <Объект> = QVideoWidget([parent=None]) В параметре parent может быть указана ссылка на родительский компонент. Методов класс QVideoWidget поддерживает относительно немного, и все они управляют выводом видео: setFullScreen(<Флаг>) — если передать значение True , воспроизводящееся видео займет весь экран. Если передать значение False , оно займет лишь саму панель. Метод является слотом; 684 Часть II. Библиотека PyQt 5 isFullScreen() — возвращает True , если воспроизводящееся видео занимает весь экран, и False , если оно выводится лишь в самой панели; setAspectRatioMode(<Соотношение сторон>) — задает режим управления соотношением сторон при масштабировании видео. В качестве результата указывается один из сле- дующих атрибутов класса QtCore.Qt : • IgnoreAspectRatio — 0 — соотношение сторон при масштабировании видео не со- блюдается, в результате чего видео может выводиться сжатым или вытянутым; • KeepAspectRatio — 1 — соотношение сторон соблюдается. Видео масштабируется так, чтобы полностью вместиться в панель или экран, но при этом какая-то часть панели или экрана может оказаться незанятой; • KeepAspectRatioByExpanding — 2 — соотношение сторон соблюдается. Видео мас- штабируется так, чтобы полностью занять панель (экран), но при этом какая-то часть видео может выйти за ее границы. Метод является слотом; aspectRatioMode() — возвращает обозначение режима управления соотношением сто- рон при масштабировании видео; setBrightness(<Яркость>) — задает яркость видео в виде числа от -100 до 100 : отрица- тельные значения делают видео более темным, положительные — более светлым, а 0 устанавливает яркость по умолчанию. Метод является слотом; brightness() — возвращает яркость видео; setContrast(<Контрастность>) — задает контрастность видео в виде числа от -100 до 100 : отрицательные значения делают видео менее контрастным, положительные — более контрастным, а 0 устанавливает значение этого параметра по умолчанию. Метод является слотом; contrast() — возвращает контрастность видео; setHue(<Оттенок>) — задает оттенок видео в виде числа от -100 до 100 : значения, отлич- ные от 0 , изменяют цветность видео, а 0 устанавливает значение этого параметра по умолчанию. Метод является слотом; hue() — возвращает значение оттенка видео; setSaturation(<Насыщенность>) — задает насыщенность видео в виде числа от -100 до 100 : отрицательные значения делают видео менее насыщенным, положительные — более насыщенным, а 0 устанавливает значение этого параметра по умолчанию. Метод является слотом; saturation() — возвращает насыщенность видео; mediaObject() — возвращает ссылку (экземпляр класса QMediaObject ) на мультимедий- ный проигрыватель, выводящий видео в эту панель, или None , если панель не привязана к проигрывателю. Класс QVideoWidget поддерживает некоторое количество сигналов, генерируемых при изме- нении различных параметров видео (режима управления соотношением сторон, яркости, контрастности и т. д.). Описание этих сигналов приведено на странице https://doc.qt.io/qt-5/ qvideowidget.html Мы можем превратить написанную ранее программу аудиопроигрывателя в инструмент для воспроизведения видео (рис. 28.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; |