我已经看到其他一些问题如此流传,但似乎很多问题都没有得到解决或与我的情况无关,所以就这样了。
我试图在mongodb集合上播放存储为序列化数据(通过pickle)的视频。
以下是代码:
binary_file = my_database_entry['binary video']
unpickle = pickle.dumps(binary_file)
outByteArray = QByteArray(unpickle)
mediaStream = QBuffer()
mediaStream.setBuffer(outByteArray)
mediaStream.open(QIODevice.ReadWrite)
mediaPlayer.setMedia(QMediaContent(), mediaStream)
mediaPlayer.play()
其中' my_database_entry'是mongoDB条目和'二进制视频'是pickle视频条目的字典键。 这也假设mediaPlayer在我的用户界面中正确创建和初始化,即
mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
videoPlayer = QVideoWidget()
mediaPlayer.setVideoOutput(videoPlayer)
我还尝试使用' QMediaPlayer.StreamPlayback'来初始化mediaPlayer。旗帜但又一次没有。
当我在Windows上试用它时会崩溃,当我在Mac上试用它时,它只是一个黑屏。没有错误记录或任何事情(无论如何都没有任何启发)。
有没有人能够成功地为他们工作,如果是这样,你是怎么做到的?
谢谢! -Mark
答案 0 :(得分:3)
您需要保留对缓冲区和基础数据的引用,否则它们将在播放器启动后进行垃圾收集。
请注意,在你的例子中,视频数据是完全没有意义的,因为它只是字节,所以没有什么值得序列化的。 Pickle仅对结构化python对象有用,例如list
或dict
。
下面是一个带有完整视频播放器的演示脚本。它最初从文件系统获取视频资源,但如果它来自数据库,它将会起作用:
from PyQt5 import QtCore, QtWidgets
from PyQt5 import QtMultimedia, QtMultimediaWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.player = QtMultimedia.QMediaPlayer(self)
self.viewer = QtMultimediaWidgets.QVideoWidget(self)
self.player.setVideoOutput(self.viewer)
self.player.stateChanged.connect(self.handleStateChanged)
self.button1 = QtWidgets.QPushButton('Play', self)
self.button2 = QtWidgets.QPushButton('Stop', self)
self.button1.clicked.connect(self.handleButton)
self.button2.clicked.connect(self.player.stop)
self.button2.setEnabled(False)
layout = QtWidgets.QGridLayout(self)
layout.addWidget(self.viewer, 0, 0, 1, 2)
layout.addWidget(self.button1, 1, 0)
layout.addWidget(self.button2, 1, 1)
self._buffer = QtCore.QBuffer(self)
self._data = None
def handleButton(self):
path = QtWidgets.QFileDialog.getOpenFileName(self)[0]
if path:
self.button1.setEnabled(False)
self.button2.setEnabled(True)
with open(path, 'rb') as stream:
self._data = stream.read()
self._buffer.setData(self._data)
self._buffer.open(QtCore.QIODevice.ReadOnly)
self.player.setMedia(
QtMultimedia.QMediaContent(), self._buffer)
self.player.play()
def handleStateChanged(self, state):
if state == QtMultimedia.QMediaPlayer.StoppedState:
self._buffer.close()
self._data = None
self.button1.setEnabled(True)
self.button2.setEnabled(False)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 50, 640, 480)
window.show()
sys.exit(app.exec_())
<强>更新强>:
上述解决方案仅适用于Windows和Linux,因为目前OSX上不支持流式传输: