2016-12-14 4 views
1

다른 질문이 많이 생겼습니다. 그러나 그 중 많은 부분이 해결되지 않았거나 내 상황과 관련이없는 것으로 보입니다.PyQt5 - 스트림에서 비디오를 재생할 수 없습니다.

mongodb 컬렉션에서 피클을 통해 직렬화 된 데이터로 저장된 비디오를 재생하려고합니다. 'my_database_entry'는 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() 

는 절인 비디오 항목에 대한 사전 열쇠입니다 :

여기에 코드입니다. 이 또한 MediaPlayer를 제대로 만들어 내 사용자 인터페이스 즉, 나는 또한 'QMediaPlayer.StreamPlayback'플래그와 MediaPlayer를 초기화 시도

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

그러나 다시, 아무것도 내에서 초기화되어 있다고 가정합니다.

Windows에서해볼 때 충돌이 발생하며 Mac에서 시도 할 때 검은 색 화면이됩니다. 오류 로그가 없거나 아무 것도 없습니다 (어떤 경우에도 깨달음이 없습니다).

누구나 성공적으로이 문제를 해결 한 사람이 있습니까? 그렇다면 어떻게 했습니까?

감사합니다! -Mark

답변

3

버퍼와 기본 데이터 모두에 대한 참조를 유지해야합니다. 그렇지 않으면 플레이어 시작 후 가비지 수집됩니다.

예를 들어, 비디오 데이터는 단지 바이트이므로 절대로 무의미한 것이므로 직렬화 할만한 가치가 없습니다. 피클은 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_()) 

UPDATE :

위의 솔루션만이 작업

  • 참조 : Qt Multimedia Backends
  • ,691,363 윈도우와 리눅스, OSX에 스트리밍에 대한 지원은 현재이 없기 때문에210
+0

정확히 그랬습니다. 완벽하게 작동합니다. 제 경우에는 간결하게 설명하지 않았습니다. 데이터를 작동시키기 위해서는 여전히 데이터를 unpickle 할 필요가있었습니다. Unpickling은 기본적으로 'open (path,'rb ') with stream :'코드와 같은 라인을 사용했습니다. 다시 한 번 감사드립니다! – huitlacoche

+0

그래서이 방법으로 문제가 발생했습니다. 그것은 윈도우 머신에서 잘 작동하지만 OSX로가는 것은 단지 검은 스크린을 얻는다. 눈에 띄는 오류는 없습니다. 아마 이런 종류의 Mac 관련 버그일까요? – huitlacoche

+0

@huitlacoche. 나는 리눅스 만 시도해 보았고 OSX에서 직접 테스트 할 수는 없다. 문제를 일으키는 미디어 자체 일 수 있으므로 몇 가지 다른 비디오 형식을 사용해 보시기 바랍니다. 파일 URL을 사용하여 동일한 미디어를 직접로드하려고 시도 했습니까? Qt Multimedia가 얼마나 믿을만한지는 알지 못합니다. 진지한 프로젝트에서 사용하지 못했기 때문입니다. (PS : Linux에서 파일을 몇 번 더 시험해 보았습니다. 하나 또는 두 개의 파일이 성공적으로로드되지 않았습니다. 이유는 확실하지 않습니다.) – ekhumoro

관련 문제