PyQt5:QMediaPlayer 无法从 QBuffer 重放音频 [英] PyQt5 : QMediaPlayer can't replay audio from QBuffer
问题描述
我在 RAM 中有一个 QBuffer
和一个临时 wav 文件,我想让用户从任何点听他想要的次数.但是,它只允许播放一次,不允许重播.如果我从文件 (QUrl.fromLocalFile
) 播放音频,它可以重播.有什么不同?如何解决?
I have a QBuffer
in RAM with a temporary wav file, and I want to let the user listen it from any point as many times as (s)he want. But, it only allows playing it once, and doesn't allow replaying it. If I play the audio from a file (QUrl.fromLocalFile
), it can replay it. What's the difference? How to fix it?
1) 要从 RAM 播放 wav 文件,我使用以下代码:
1) To play the wav file from RAM I use the following code:
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()
的所有后续调用都无效.这不是我想要的.
Then, if I call self.mediaplayer.play()
, it will play the file to the end. But, all subsequent calls to self.mediaplayer.play()
have no effect. This is not what I want.
2) 如果我从文件中初始化 mediaplayer,使用:
2) If I init mediaplayer from a file, with:
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile("/home/me/myTestApp/test.wav")))
它工作正常 - 如果我在上一次播放结束后调用 play()
,QMediaPlayer 只会重复播放.
it works OK - if i call play()
after the previous playback is over, QMediaPlayer just repeats the playback.
推荐答案
A QBuffer 是一个 io 设备 - 一旦你阅读了它,你需要重置它的位置才能再次阅读它.所以在你的代码中你需要做这样的事情:
A QBuffer is an io-device - once you've read it, you need to reset its position in order to read it again. So in your code you will need to do something like this:
...
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 后端):
After some actual testing, I found that it is only necessary to keep a reference to the buffer in order to replay the audio. The script below is a complete example that works fine for me (on Linux, using the GStreamer backend):
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_())
这篇关于PyQt5:QMediaPlayer 无法从 QBuffer 重放音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!