ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
Глава 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; Глава 28. Мультимедиа 693 • ConstantBitRateEncoding — 1 — режим кодирования с постоянным битрейтом. Бит- рейт устанавливается вызовом метода setBitRate() , а значение качества соответст- венно выбирается самой PyQt; • AverageBitRateEncoding — 2 — режим кодирования с переменным битрейтом. В этом случае метод setBitRate() задает величину среднего битрейта; • TwoPassEncoding — 3 — режим кодирования в два прохода; setBitRate(<Битрейт>) — задает битрейт кодирования звука, выраженный в битах в се- кунду. Его имеет смысл указывать только в том случае, если задан режим кодирования с по- стоянным битрейтом (атрибут ConstantBitRateEncoding ), с переменным битрейтом (ат- рибут AverageBitRateEncoding ) или кодирование в два прохода (атрибут TwoPassEncoding ); setQuality(<Качество кодирования>) — задает качество кодирования звука. В качестве параметра указывается значение одного из следующих атрибутов класса QMultimedia : • VeryLowQuality — 0 — самое низкое качество; • LowQuality — 1 — низкое качество; • NormalQuality — 2 — нормальное качество; • HighQuality — 3 — высокое качество; • VeryHighQuality — 4 — наивысшее качество. Качество кодирования имеет смысл указывать только в том случае, если задан режим кодирования с постоянным качеством (атрибут ConstantQualityEncoding ); setEncodingOption(<Параметр>, <Значение>) — задает значение для указанного пара- метра кодирования. Наименование параметра кодирования задается в виде строки; setEncodingOptions(<Словарь>) — задает сразу несколько параметров кодирования зву- ка. В параметре передается словарь, ключи которого представляют собой наименования параметров кодирования, а их значения — значения соответствующих параметров. Набор поддерживаемых параметров кодирования зависит от выбранного звукового ко- дека. Для примера напишем простую утилиту (листинг 28.5), осуществляющую запись звука с микрофона в минимальном качестве, — своего рода программный диктофон (рис. 28.4). Листинг 28.5. Утилита для записи звука с микрофона 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.ardRecorder = QtMultimedia.QAudioRecorder() # Устанавливаем максимальную громкость self.ardRecorder.setVolume(100) 694 Часть II. Библиотека PyQt 5 # Звук будет сохраняться в файле record.wav, находящемся # в той же папке, где хранится программа fn = QtCore.QUrl.fromLocalFile(os.path.abspath("record.wav")) self.ardRecorder.setOutputLocation(fn) # Устанавливаем звуковой вход по умолчанию self.ardRecorder.setAudioInput(self.ardRecorder.defaultAudioInput()) # Указываем формат файла WAV self.ardRecorder.setContainerFormat("audio/x-wav") # Задаем параметры кодирования звука aes = QtMultimedia.QAudioEncoderSettings() aes.setCodec("audio/pcm") aes.setSampleRate(8000) aes.setChannelCount(1) aes.setEncodingMode (QtMultimedia.QMultimedia.ConstantQualityEncoding) aes.setQuality(QtMultimedia.QMultimedia.VeryLowQuality) self.ardRecorder.setAudioSettings(aes) self.ardRecorder.statusChanged.connect(self.initRecorder) self.ardRecorder.durationChanged.connect(self.showDuration) # Создаем компоненты для запуска, приостановки и остановки # записи звука и регулирования его уровня vbox = QtWidgets.QVBoxLayout() hbox = QtWidgets.QHBoxLayout() self.btnRecord = QtWidgets.QPushButton("&Запись") self.btnRecord.clicked.connect(self.ardRecorder.record) hbox.addWidget(self.btnRecord) self.btnPause = QtWidgets.QPushButton("П&ауза") self.btnPause.clicked.connect(self.ardRecorder.pause) self.btnPause.setEnabled(False) hbox.addWidget(self.btnPause) self.btnStop = QtWidgets.QPushButton("&Стоп") self.btnStop.clicked.connect(self.ardRecorder.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(100) lblVolume.setBuddy(sldVolume) sldVolume.valueChanged.connect(self.ardRecorder.setVolume) hbox.addWidget(sldVolume) vbox.addLayout(hbox) # Создаем надпись, в которую будет выводиться состояние программы self.lblStatus = QtWidgets.QLabel("Готово") vbox.addWidget(self.lblStatus) Глава 28. Мультимедиа 695 self.setLayout(vbox) self.resize(300, 100) # В зависимости от состояния записи звука делаем нужные # кнопки доступными или, напротив, недоступными и выводим # соответствующий текст в надписи def initRecorder(self, status): if status == QtMultimedia.QMediaRecorder.RecordingStatus: self.btnRecord.setEnabled(False) self.btnPause.setEnabled(True) self.btnStop.setEnabled(True) self.lblStatus.setText("Запись") elif status == QtMultimedia.QMediaRecorder.PausedStatus: self.btnRecord.setEnabled(True) self.btnPause.setEnabled(False) self.lblStatus.setText("Пауза") elif status == QtMultimedia.QMediaRecorder.FinalizingStatus: self.btnRecord.setEnabled(True) self.btnPause.setEnabled(False) self.btnStop.setEnabled(False) self.lblStatus.setText("Готово") # Выводим продолжительность записанного звука def showDuration(self, duration): self.lblStatus.setText("Записано " + str(duration // 1000) + " секунд") app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) Рис. 28.4. Утилита для записи звука 28.5. Класс QSoundEffect Класс QSoundEffect предоставляет средства воспроизведения коротких звуковых файлов, что может пригодиться, скажем, для информирования пользователя о каком-либо событии. Конструктор этого класса имеет следующий формат вызова: <Объект> = QSoundEffect([parent=None]) В параметре parent может быть указана ссылка на родительский компонент. 696 Часть II. Библиотека PyQt 5 Класс QSoundEffect поддерживает следующие основные методы (полный их список можно найти на странице https://doc.qt.io/qt-5/qsoundeffect.html): setSource( — задает файл-источник воспроизводимого звука в виде экземпляра класса QUrl ; setVolume(<Громкость>) — задает громкость воспроизводимого звука в виде веществен- ного числа от 0.0 (звук отключен) до 1.0 (максимальная громкость); setLoopCount(<Количество повторений>) — задает количество повторений звука при воспроизведении. Значение 0 или 1 предписывает воспроизвести звук всего один раз, а значение атрибута Infinite класса QSoundEffect или -2 — воспроизводить его снова и снова бесконечное количество раз; setCategory(<Категория>) — задает наименование категории (указывается в виде стро- ки), к которой относится воспроизводимый звук; setMuted(<Флаг>) — если передать значение True , звук при воспроизведении будет от- ключен. Значение False вновь включает звук; play() — запускает воспроизведение звука. Метод является слотом; stop() — останавливает воспроизведение звука. Метод является слотом; isLoaded() — возвращает True , если звук загружен из указанного в методе setSource() файла, и False — в противном случае; isPlaying() — возвращает True , если звук в текущий момент воспроизводится, и False — в противном случае; loopsRemaining() — возвращает количество оставшихся повторов воспроизведения зву- ка или значение атрибута Infinite класса QSoundEffect , если было задано бесконечное воспроизведение; volume() — возвращает текущее значение громкости звука в виде вещественного числа от 0.0 до 1.0; loopCount() — возвращает количество повторений звука, заданное вызовом метода setLoopCount() ; isMuted() — возвращает True , если воспроизводящийся звук в текущий момент отклю- чен, и False — в противном случае; status() — возвращает текущее состояние звука в виде значения одного из следующих атрибутов класса QSoundEffect : • Null — 0 — источник звука не задан; • Loading — 1 — идет загрузка звука из файла-источника; • Ready — 2 — звук загружен и готов к воспроизведению; • Error — 3 — в процессе загрузки звука возникла ошибка; supportedMimeTypes() — возвращает список наименований поддерживаемых форматов звука в виде строк: for f in QtMultimedia.QSoundEffect.supportedMimeTypes(): print(f, end = " ") Выведет: audio/x-wav audio/wav audio/wave audio/x-pn-wav Метод является статическим. Глава 28. Мультимедиа 697 Как видим, поддерживается лишь формат WAV в виде четырех различных MIME-типов. Что касается аудиокодеков, то, по результатам экспериментов авторов, поддерживается лишь кодек PCM. Класс QSoundEffect поддерживает следующие наиболее полезные для нас сигналы (полный их список можно найти на странице https://doc.qt.io/qt-5/qsoundeffect.html): statusChanged() — генерируется при изменении состояния звука; loadedChanged() — генерируется при изменении состояния загрузки звука из файла- источника; playingChanged() — генерируется при изменении состояния воспроизведения звука; loopsRemainingChanged() — генерируется при каждом повторении воспроизводимого звука; volumeChanged() — генерируется при изменении громкости звука; mutedChanged() — генерируется при отключении звука или, наоборот, восстановлении его громкости через вызов метода setMuted() Примером к этому разделу станет небольшая программа, воспроизводящая звук, в зависи- мости от выбора пользователя: единожды, десять раз или бесконечно (листинг 28.6). Листинг 28.6. Воспроизведение звуковых эффектов 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.sndEffect = QtMultimedia.QSoundEffect() self.sndEffect.setVolume(1) # Задаем файл-источник fn = QtCore.QUrl.fromLocalFile(os.path.abspath("effect.wav")) self.sndEffect.setSource(fn) self.sndEffect.loopsRemainingChanged.connect(self.showCount) self.sndEffect.playingChanged.connect(self.clearCount) vbox = QtWidgets.QVBoxLayout() # Создаем кнопки для запуска воспроизведения звука lblPlay = QtWidgets.QLabel("Воспроизвести...") vbox.addWidget(lblPlay) btnOnce = QtWidgets.QPushButton("...&один раз") btnOnce.clicked.connect(self.playOnce) vbox.addWidget(btnOnce) btnTen = QtWidgets.QPushButton("...&десять раз") btnTen.clicked.connect(self.playTen) vbox.addWidget(btnTen) btnInfinite = QtWidgets.QPushButton( "...&бесконечное количество раз") 698 Часть II. Библиотека PyQt 5 btnInfinite.clicked.connect(self.playInfinite) vbox.addWidget(btnInfinite) btnStop = QtWidgets.QPushButton("&Стоп") btnStop.clicked.connect(self.sndEffect.stop) vbox.addWidget(btnStop) self.lblStatus = QtWidgets.QLabel("") vbox.addWidget(self.lblStatus) self.setLayout(vbox) self.resize(200, 100) def playOnce(self): self.sndEffect.setLoopCount(1) self.sndEffect.play() def playTen(self): self.sndEffect.setLoopCount(10) self.sndEffect.play() def playInfinite(self): self.sndEffect.setLoopCount(QtMultimedia.QSoundEffect.Infinite) self.sndEffect.play() # Выводим количество повторений воспроизведения эффекта def showCount(self): self.lblStatus.setText("Воспроизведено " + str(self.sndEffect.loopCount() - self.sndEffect.loopsRemaining()) + " раз") # Если воспроизведение закончено, очищаем выведенное ранее # количество повторений эффекта def clearCount(self): if not self.sndEffect.isPlaying(): self.lblStatus.setText("") app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) П РИМЕЧАНИЕ Помимо описанных здесь возможностей, PyQt 5 поддерживает доступ к устройствам вос- произведения звука на низком уровне, а также получение непосредственно массива звуко- вых и видеоданных с целью их анализа и обработки. Соответствующие программные инст- рументы описаны в документации по этой библиотеке. |