Как правильно воспроизвести видео в композиторе GStreamer с динамическим связыванием? - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть приложение Python, которое использует GStreamer для потоковой передачи видео на RTMP-сервер.

Видео построено с использованием элемента Compositor из многих типов исходных видео:

  • в начале есть только фон (filesrc -> decodebin -> videoconvert -> imagefreeze -> capsfilter -> cairooverlay -> compositor)
  • , через некоторое время пользователь WebRTC подключается, и у композитора появляется новый источник webrtcbin -> h264parse -> avdec_h264 -> videoconvert -> videorate -> capsfilter -> videobox -> tee -> compositor
  • и, наконец, источник проблемы - Воспроизведение видео из файла : filesrc -> decodebin -> queue -> compositor

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

Мне удалось получить время работы для композитора, но вызов set_offset на любой панели видеобаней делает видео вообще не воспроизводимым (продолжительностькажется правильным, но на композиторе видно всего несколько кадров всего видео).

1 Ответ

0 голосов
/ 21 сентября 2018

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

Этот код позволил мне воспроизводить видео с декодера на прямую трансляцию:

После загрузки файла с декодером (добавлено pad):

self.video_selector_pad = self.pipeline.output_video_selector.get_request_pad("sink_%u")
self.video_out_pad = self.video_queue.get_static_pad("src") #  decodebin pad is linked to this queue
self.video_out_pad.use_fixed_caps()
self.video_out_pad.add_probe(Gst.PadProbeType.EVENT_DOWNSTREAM, self._on_video_downstream_event, None)
self.video_out_pad.set_active(False)

По запросу пользователя:

compositor_running_time = self.pipeline.output_video_selector_compositor_pad.get_property("running-time")
self.video_out_pad.set_offset(compositor_running_time)
self.pipeline.output_video_selector.set_property("active-pad", self.video_selector_pad)
self.video_out_pad.set_active(True)

# send seek event as we want to play it from t = 0
    seek_event = Gst.Event.new_seek(
        1.0,
        Gst.Format.TIME,
        Gst.SeekFlags.FLUSH,
        Gst.SeekType.SET,
        0,
        Gst.SeekType.NONE,
        0
    )
...