【问题标题】:PyQt5 -- Unable to playback video from streamPyQt5 - 无法从流中播放视频
【发布时间】:2016-12-14 19:00:13
【问题描述】:

我看到过很多类似这样的其他问题,但似乎其中许多问题没有解决或与我的情况无关,所以就这样吧。

我正在尝试在 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 条目,而 'binary video' 是腌制视频条目的字典键。 这还假设在我的用户界面中正确创建和初始化了 mediaPlayer,即

    mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
    videoPlayer = QVideoWidget()
    mediaPlayer.setVideoOutput(videoPlayer)

我还尝试使用“QMediaPlayer.StreamPlayback”标志初始化 mediaPlayer,但同样没有。

当我在 windows 上尝试它时它崩溃了,当我在 mac 上尝试它时它只是一个黑屏。没有错误日志或任何东西(无论如何都没有启发性)。

有没有人成功地为他们工作,如果有,你是怎么做到的?

谢谢! -马克

【问题讨论】:

    标签: python qt pyqt pyqt5


    【解决方案1】:

    您需要保留对缓冲区和基础数据的引用,否则它们将在播放器启动后被垃圾回收。

    请注意,在您的示例中,腌制视频数据完全没有意义,因为它只是字节,因此没有什么值得序列化的。 Pickle 仅对结构化的 Python 对象有用,例如 listdict

    下面是一个带有完整视频播放器的演示脚本。它最初从文件系统中获取视频资源,但如果它来自数据库,它的工作方式也一样:

    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 上不支持流式传输:

    【讨论】:

    • 就是这样。完美运行。就我而言,为了简洁起见,我没有很好地解释它。我仍然需要解开数据才能使其正常工作。 Unpickling 基本上取代了代码中的 'with open(path, 'rb') as stream:' 等行。再次感谢!!
    • 所以我遇到了这个方法的一些问题。它在 Windows 机器上运行良好,但转到 OSX 我只是得到一个黑屏。没有明显的错误。这可能是某种特定于 mac 的错误吗?
    • @huitlacoche。我只在 Linux 上试过,不能在 OSX 上自己测试。可能是媒体本身导致了问题,所以我建议您尝试几种不同的视频格式。您是否尝试过使用文件 url 直接加载相同的媒体?我不知道 Qt Multimedia 一般有多可靠,因为我从未在严肃的项目中真正使用过它。 (PS:我只是在Linux上多试了几个文件,一两个没有加载成功——不知道为什么)。
    • @huitlacoche。 PPS:我尝试使用文件 url 直接加载有问题的文件,但它们仍然没有加载 - 所以它没有从导致问题的缓冲区中读取。并且使用 mplayer 可以正常加载相同的文件,因此似乎存在一些内部 Qt 问题。
    • 我不确定它的来源。我可以从文件 url 加载视频。我会继续玩它的。至少我知道它可以工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 2018-05-13
    • 2015-11-11
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多