1

QBuffer在 RAM 中有一个带有临时 wav 文件的文件,我想让用户在任何时候都可以听到他想要的次数。但是,它只允许播放一次,并且不允许重播。如果我从文件 ( QUrl.fromLocalFile) 播放音频,它可以重播它。有什么不同?如何解决?

1)要从 RAM 播放 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 只会重复播放。

4

1 回答 1

2

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_())
于 2017-10-19T19:57:33.377 回答