2016-12-14 4 views
1

Я видел ряд других вопросов, подобных этому, но кажется, что многие из них неразрешены или не связаны с моей ситуацией, так что здесь идет.PyQt5 - Невозможно воспроизвести видео из потока

Я пытаюсь воспроизвести видео, записанное в виде сериализованных данных (через рассол) в коллекции mongodb.

Вот код:

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 и «двоичное видео» является ключом словаря для маринованной записи видео. Это также предполагает, что MediaPlayer правильно создается и инициализируется в моем пользовательском интерфейсе т.е.

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

Я также попытался инициализацией медиаплеера с флагом «QMediaPlayer.StreamPlayback», но опять же, ничего.

Он падает, когда я пытаюсь использовать его в окнах, и это просто черный экран, когда я пытаюсь использовать его на Mac. Нет журналов ошибок или чего-либо (ничего не просвещать в любом случае).

Кто-нибудь получил это, чтобы успешно работать на них, и если да, то как вы это сделали?

Спасибо! -Mark

ответ

3

Вам необходимо сохранить ссылку на буфер и базовые данные, иначе они будут собираться только после сбора мусора.

Обратите внимание, что в вашем примере совершенно бессмысленно травить видеоданные, так как это просто байты, и поэтому ничего не стоит сериализовать. Pickle полезен только для структурированных объектов python, таких как list или dict.

Ниже приведен демонстрационный сценарий с полным видеоплеером. Это Initally получает видео ресурс из файловой системы, но она будет работать точно так же, если он пришел из базы данных:

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_()) 

UPDATE:

Решение выше будет только работа на Windows, и Linux, потому что в настоящее время нет поддержки для прослушивания на OSX:

+0

Это было именно оно. Работает отлично. В моем случае я недостаточно объяснил это для краткости. Мне все еще нужно было распечатать данные, чтобы они работали. Unpickling в основном заменил строку «open» (путь, «rb») как поток: 'и т. Д. Вашего кода. Еще раз спасибо!! – huitlacoche

+0

Поэтому я столкнулся с проблемой с этим методом. Он отлично работает на Windows-машине, но, перейдя на OSX, я просто получаю черный экран. Нет заметной ошибки. Может быть, это какая-то ошибка, специфичная для Mac? – huitlacoche

+0

@huitlacoche. Я только пробовал Linux, и сам не могу проверить его на OSX. Это может быть сам носитель, который вызывает проблему, поэтому я предлагаю вам попробовать несколько разных видеоформатов. Вы пытались загрузить один и тот же носитель напрямую с помощью URL-адреса файла? Я не знаю, насколько надежна Qt Multimedia в целом, поскольку я никогда не использовал ее в серьезном проекте. (PS: Я просто попробовал еще несколько файлов в Linux, и один или два не загружались успешно - не знаю почему). – ekhumoro

 Смежные вопросы

  • Нет связанных вопросов^_^