InterpolationControlSource с Gst.parse_launch ()

Мое приложение (на Python) загружает библиотеку Gstreamer, анализирует и запускает спецификацию конвейера, которая объединяет субтитры из файла SRT поверх подготовленного видео из файла MP4, а затем создает источник управления с привязкой к свойству 'alpha' панели приемника элемента videomixer, который связан с источником изображения субтитров.

Сначала я написал небольшое доказательство концепции, которое работает как чемпион. Если вы можете запустить его с сервером X-windows (например, в Unix или Linux), вы увидите черный квадрат на зеленом фоне. Через секунду черный квадрат постепенно гаснет в течение нескольких секунд.

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

pipeline_spec = '''
videomixer name=mixer ! ... other stuff downstream
filesrc location=sample_videos/my-video.mp4 ! decodebin name=demuxer ! mixer.sink_0
filesrc location=subtitles.srt ! subparse ! textrender ! mixer.sink_1
demuxer. ! audioconvert ! audioresample ! faac ! muxer.
'''

self.pipeline = Gst.parse_launch(pipeline_spec)
mixer = self.pipeline.get_by_name('mixer')
#vidpad = mixer.get_static_pad('sink_0')
srtpad = mixer.get_static_pad('sink_1')
self.logger.debug([ pad.name for pad in mixer.pads ])

cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
binding = GstController.DirectControlBinding.new(srtpad, 'alpha', cs)
cs.add_control_binding(binding)

with open(srtfilepath) as srtfile:
    for timestamps in parsesrt.parse(srtfile):
        start, end = timestamps
        self._set_subtitle_fade(alpha_cs, start, end)

def _set_fade_effect(self, controlsource, start, duration, alpha_begin, alpha_end):
    controlsource.set(start, alpha_begin)
    controlsource.set(start + duration, alpha_end)
    self.logger.debug('set fade-{0} from {1} to {2}'.format('in' if alpha_begin < alpha_end else 'out', start, start + duration))

def _set_subtitle_fade(self, controlsource, start_subtitle, end_subtitle):
    self._set_fade_effect(controlsource, start_subtitle, self.DURATION_FADEIN, 0, 1)
    self._set_fade_effect(controlsource, end_subtitle - self.DURATION_FADEOUT, self.DURATION_FADEOUT, 1, 0)

Одно различие между этими двумя конвейерами состоит в том, что в первом примере панели видеомикшера - это панели запроса. Но в реальном приложении они оказываются статическими площадками. И в операторе журнала присутствует только «сток_1».

DEBUG, ['src', 'sink_1']

Я не уверен, почему это так и имеет ли это значение.

Когда я запускаю приложение на веб-сервере и проверяю его в браузере, субтитры появляются, но не исчезают и не исчезают.

Я проверил временные метки, и они выглядят хорошо. Они указаны в наносекундах (10 ^ 9).

set fade-in from 2440000000 to 3440000000
set fade-out from 2375000000 to 4375000000
set fade-in from 7476000000 to 8476000000
...

Итак, какой камень я оставил неперевёрнутым?


person Lawrence I. Siden    schedule 13.03.2017    source источник


Ответы (1)


Другое большое различие между вашим первым и вторым прототипами - videotestsrc переход на filesrc ! decodebin. gst_parse_launch не будет сразу подключать decodebin к videomixer. Произойдет вот что:

  • Конвейер анализируется, но decodebin не знает содержимое filesrc, пока не распакует его. Это может быть аудио или презентация PowerPoint, или подпись PGP, или что-нибудь еще. Поэтому изначально он не возвращает src pads.

  • Вы играете в конвейер. decodebin начинает получать данные от filesrc, идентифицирует контент как mp4 и демультиплексирует его. Он обнаруживает, что у него есть видеоконтент, соответствующий площадкам для videomixer, и устанавливает соединение с первой открытой площадкой.

Итак, что вам, вероятно, нужно сделать, так это прослушать событие pad-added в decodebin, проверить, что это правильный контакт, а затем выполнить привязку.

def decodebin_pad_added(self, decodebin, pad):
  #return if pad is wrong type

  #make the binding to the pad

decodebin.connect("pad_added", decodebin_pad_added)

Вы можете узнать, что такое поведение будет присутствовать, запустив gst-inspect-1.0 на рассматриваемом элементе и проверив контактные площадки. Вы можете видеть, что у decodebin есть шаблон заполнения "иногда" по сравнению с постоянным заполнителем, который присутствует в subparse:

subparse:
Pads:
...
  SRC: 'src'
    Implementation:
      Has custom eventfunc(): gst_sub_parse_src_event
      Has custom queryfunc(): gst_sub_parse_src_query
      Has custom iterintlinkfunc(): gst_pad_iterate_internal_links_default
    Pad Template: 'src'

decodebin:
Pad Templates:
  SRC template: 'src_%u'
    Availability: Sometimes
    Capabilities:
      ANY
person mpr    schedule 14.03.2017
comment
Спасибо @mpr! Я попробую, а потом вернусь к вам. - person Lawrence I. Siden; 16.03.2017
comment
gst-inspect decodebin показывает всевозможные полезные свойства, такие как сигнал с добавлением контактных площадок. Но какая у вас версия gst-plugins-base. Моя версия не показывает настраиваемую функцию eventfunc () для панели subparse.src. Я использую версию 1.8.1 плагинов. - person Lawrence I. Siden; 16.03.2017
comment
Я на 1.6. Я не уверен, что вам нужно беспокоиться об этих пользовательских функциях, думаю, они просто информационные. - person mpr; 16.03.2017
comment
Я хочу подключить свой источник управления к приемнику видеомикшера, который получает визуализированный текст субтитров. Я установил прослушиватель для добавления пэда на видеомикшере, но слушатель вызывается только один раз и pad.get_name () == ›'ink_0 '. Но должна быть вторая раковина, "раковина_1". Я что-то еще упускаю? - person Lawrence I. Siden; 16.03.2017
comment
Я предполагаю, что вы не получаете событие pad-added для стока_1, потому что вы добавляете прослушиватель событий после того, как конвейер анализирует и подключает то, что он может. Для этого, возможно, вы можете просто получить его по имени, используя gst_element_get_static_pad(). - person mpr; 16.03.2017
comment
Я только что создал суть, которая показывает мой вывод отладки из теста конвейера: gist.github.com/lsiden/48b0b05370fb43. Теперь он отправляет визуализированный текст в videomixer.sink_0, который является статической панелью. Приемник_1 подключается к декодированному видеопотоку после запуска конвейера. Так что это должно работать сейчас, но это не так. - person Lawrence I. Siden; 16.03.2017
comment
Итак, вы говорите, что все это связано, но затем, когда вы меняете значения в ползунках, это ничего не делает? - person mpr; 16.03.2017
comment
Вот как это выглядит. Я только что добавил видео / x-raw, высота-540! смеситель ... перед каждым из смесителей опускается. Теперь обе колодки доступны при запуске. Субтитры снова подключены к videomixer.sink_1. По-прежнему нет эффекта затухания. Я боялся, что временные метки могут быть неправильными, но я подтвердил, что они находятся в наносекундах (10 ^ 9) и соответствуют временным меткам субтитров. - person Lawrence I. Siden; 16.03.2017
comment
Позвольте нам продолжить это обсуждение в чате. - person mpr; 16.03.2017
comment
Если вам все еще интересно, я обновил gist.github.com/lsiden/48b0b05370fb43e7f43f932bee с помощью мой последний вывод отладки. - person Lawrence I. Siden; 16.03.2017