PyQt5 QtMultimedia показывает черный экран при воспроизведении видео H.264

Мы используем инструмент на основе PyQt5 для обработки видео. Уже несколько дней некоторые пользователи жалуются, что инструмент показывает только черный экран вместо видео. Звук все еще работает. Нам удалось воспроизвести эту проблему с помощью небольшого скрипта:

import os
from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, path, parent=None):
        super(MainWindow, self).__init__(parent)

        video_widget = QtMultimediaWidgets.QVideoWidget()
        self.setCentralWidget(video_widget)
        self.player = QtMultimedia.QMediaPlayer(self, QtMultimedia.QMediaPlayer.VideoSurface)
        self.player.setVideoOutput(video_widget)
        self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(path)))
        self.player.play()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    file = "<file>.MP4"
    w = MainWindow(file)
    w.show()
    sys.exit(app.exec_())

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

0
задан 8 May 2020 в 11:12

1 ответ

Разные конвейеры для некоторых пользователей в разных системах, но не для других пользователей, указывают на проблему с VAAPI. Все работает после отключения VAAPI по инструкции на Временный пропуск декодеров vaapi в decodebin.


Иногда бывает полезно отключить vaapi из логики автоматического подключения gstreamer, например. когда есть нерешенная проблема или когда необходимо принудительно выбрать декодер в decodebin для целей тестирования.

Стандартные возможности:

  • полное удаление gstreamer-vaapi
  • переопределение системы ранжирования плагинов, чтобы понизить плагины vaapi ниже других альтернатив — для этого требуется использование gstreamer API, недоступного с gst-launch или totem.

Я нашел более простой способ: определить для LIBVA_DRIVER_NAME фальшивое значение, которое заставит vaapi не инициализироваться, а, следовательно, пропустит его плагины.

Например:

LIBVA_DRIVER_NAME=fakedriver gst-launch-1.0 playbin uri=file:///tmp/file.mp4

Без него:

$ gst-launch-1.0 playbin uri=file://`pwd`/bbb-1920-1080-30.mp4
Got context from element 'vaapisink0': gst.vaapi.Display=context, gst.vaapi.Display=(GstVaapiDisplay)"\(GstVaapiDisplayGLX\)\ vaapidisplayglx0";

С env var мы видим, что вместо этого был выбран avdec_h264:

LIBVA_DRIVER_NAME=fakedriver gst-launch-1.0 playbin uri=file://`pwd`/bbb-1920-1080-30.mp4 -v
...
/GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/avdec_h264:avdec_h264-0.GstPad:sink: caps = video/x-h264, stream-format=(string)avc, alignment=(string)au, level=(string)4.1, profile=(string)high, codec_data=(buffer)01640029ffe1001b67640029acca501e0089f970110000030001000003003c8f18319601000568e93b2c8b, width=(int)1920, height=(int)1080, framerate=(fraction)30/1, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true
0
ответ дан 23 June 2020 в 20:55

Другие вопросы по тегам:

Похожие вопросы: