PyQt5: QMediaPlayer не может воспроизводить звук из QBuffer
У меня есть QBuffer
в оперативной памяти с временным файлом WAV, и я хочу, чтобы пользователь мог слушать его из любой точки столько раз, сколько он хочет. Но он позволяет играть только один раз и не позволяет воспроизводить его. Если я проигрываю аудио из файла (QUrl.fromLocalFile
), это может воспроизвести его. Какая разница? Как это исправить?
1) Для воспроизведения файла WAV из ОЗУ я использую следующий код:
data = b""
with open(fname, "rb") as file:
data = file.read()
buf = QBuffer()
buf.setData(data) #For debugging. Real buffer is filled differently.
buf.open(QIODevice.ReadOnly);
self.mediaPlayer=QMediaPlayer(self)
self.mediaPlayer.setMedia(QMediaContent(),buf)
Тогда, если я позвоню self.mediaplayer.play()
, он будет воспроизводить файл до конца. Но все последующие звонки self.mediaplayer.play()
не имеют никакого эффекта. Это не то, что я хочу.
2) Если я запускаю медиаплеер из файла, с помощью:
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile("/home/me/myTestApp/test.wav")))
все работает хорошо - если я позвоню play()
после окончания предыдущего воспроизведения QMediaPlayer просто повторяет воспроизведение.
1 ответ
QBuffer - это io-устройство - как только вы прочитаете его, вам нужно сбросить его положение, чтобы прочитать его снова. Так что в вашем коде вам нужно будет сделать что-то вроде этого:
...
self._buffer = buf
self.mediaPlayer=QMediaPlayer(self)
self.mediaPlayer.setMedia(QMediaContent(), self._buffer)
def play(self):
self._buffer.seek(0)
self.mediaPlayer.play()
РЕДАКТИРОВАТЬ:
После некоторого реального тестирования я обнаружил, что необходимо только сохранить ссылку на буфер, чтобы воспроизвести звук. Сценарий, приведенный ниже, является полным примером, который отлично работает для меня (в Linux, с использованием бэкэнда GStreamer):
import sys
from PyQt5 import QtCore, QtWidgets, QtMultimedia
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.buttonOpen = QtWidgets.QPushButton('Open', self)
self.buttonOpen.clicked.connect(self.handleOpen)
self.buttonPlay = QtWidgets.QPushButton('Play', self)
self.buttonPlay.clicked.connect(self.handlePlay)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.buttonOpen)
layout.addWidget(self.buttonPlay)
self.mediaPlayer = QtMultimedia.QMediaPlayer(self)
self._buffer = QtCore.QBuffer()
def handlePlay(self):
if self.buttonPlay.text() == 'Play':
self.buttonPlay.setText('Stop')
# self._buffer.seek(0)
self.mediaPlayer.play()
else:
self.buttonPlay.setText('Play')
self.mediaPlayer.stop()
def handleOpen(self):
path, ok = QtWidgets.QFileDialog.getOpenFileName(
self, filter='WAV Files (*.wav)')
if ok:
self._buffer.close()
with open(path, 'rb') as stream:
self._buffer.setData(stream.read())
if self._buffer.open(QtCore.QIODevice.ReadOnly):
self.mediaPlayer.setMedia(
QtMultimedia.QMediaContent(), self._buffer)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 200, 50)
window.show()
sys.exit(app.exec_())