Meine App (in Python) lädt die Gstreamer-Bibliothek, analysiert und startet eine Pipeline-Spezifikation, die Untertitel aus einer SRT-Datei über einem vorbereiteten Video aus einer MP4-Datei zusammenfügt und anschließend ein Steuerelement erstellt Quelle mit einer Bindung an die "Alpha" -Eigenschaft des Sinkpads des Videomixers Elements, das mit der Untertitelbildquelle verknüpft ist.InterpolationControlSource mit Gst.parse_launch()
Zuerst schrieb ich eine kleine proof-of-concept, die wie ein Champion funktioniert. Wenn Sie es mit einem X-Windows-Server (beispielsweise unter Unix oder Linux) ausführen können, sehen Sie ein schwarzes Quadrat auf grünem Hintergrund. Nach einer Sekunde verblasst das schwarze Quadrat allmählich über mehrere Sekunden.
Meine App hat eine Pipeline, die ein bisschen komplexer ist. Im Folgenden finden Sie eine Zusammenfassung der relevanten Code:
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)
Ein Unterschied zwischen den beiden Pipelines ist, dass im ersten Beispiel die Videomixer Pads Anfrage Pads sind. Aber in der realen App entpuppen sie sich als statische Pads. Und nur "Senke_1" ist in der Log-Anweisung vorhanden.
DEBUG, ['src', 'sink_1']
Ich bin mir nicht sicher, warum das so ist oder ob es einen Unterschied macht.
Wenn ich die App auf einem Webserver starte und in einem Browser einchecke, erscheinen die Untertitel, aber sie werden nicht ein- oder ausgeblendet.
Ich überprüfte die Zeitstempel und sie sehen gut aus. Sie sind in Nanosekunden (10^9).
set fade-in from 2440000000 to 3440000000
set fade-out from 2375000000 to 4375000000
set fade-in from 7476000000 to 8476000000
...
Also welchen Stein habe ich unausgeschieden?
Vielen Dank @mpr! Ich werde es versuchen, dann melde ich mich wieder bei dir. –
gst-inspect decoderbin zeigt alle möglichen nützlichen Eigenschaften, wie das Pad-Add-Signal. Aber welche Version von gst-plugins-base hast du. In meiner Version wird "custom eventfunc()" für das Pad subparse.src nicht angezeigt. Ich benutze Version 1.8.1 der Plugins. –
Ich bin auf 1.6. Ich bin mir nicht sicher, ob Sie sich über diese benutzerdefinierten Funktionen Gedanken machen müssen, sondern dass sie nur informativ sind. – mpr