Wie kann man ffmpeg dazu bringen, die Untertitel während der Transcodierung in Echtzeit zu löschen?

Ich füttere ffmpeg von stdin und führe mehrere Transcodierungsvorgänge in nur einem Befehl aus. Das Problem ist, dass ffmpeg sie anscheinend nacheinander transkodiert (oder zumindest auf die Festplatte schreibt) (dh zuerst transkodiert/schreibt es Audio/Video und dann transkodiert es die Untertitel). Auf diese Weise dauert es Minuten, bis Sie Untertitelinhalte erhalten, was zu einer schlechten Benutzererfahrung führt (wenn die Transcodierung "on demand"/live ist), da der Client auf die Untertitel warten muss, selbst wenn das Audio/Video bereit ist (mindestens teilweise). Wie kann ich das ändern? Wie kann ich ffmpeg dazu bringen, die Untertitel auf die Festplatte zu schreiben, sobald sie kopiert/transkodiert werden?

Hinweis: Ich glaube, dass die Transcodierung auch für die Untertitel gleichzeitig durchgeführt wird, aber aus bestimmten Gründen werden sie erst nach Abschluss der Audio-/Video-Transcodierung auf die Festplatte geleert/geschrieben. Das liegt daran, dass ffmpeg auf keinen Fall mit dem Lesen der Eingabe von Anfang an beginnen kann, nachdem die A / V-Transcodierung abgeschlossen ist, da es nicht von stdin suchen / neu starten kann.

Unten ist ein Beispiel für meinen Befehl:

 ffmpeg -nostdin -i - -map 0:2 -c:0 webvtt -f webvtt first.vtt \
-map 0:3 -c:0 webvtt -f webvtt second.vtt \
-map 0:0 -c:0 copy -map 0:1 -c:1 aac \
-use_timeline 1 -min_seg_duration 1000000 \
-use_template 1 -init_seg_name $RepresentationID$-0.mp4s \
-media_seg_name $RepresentationID$-$Number$.mp4s \
-adaptation_sets "id=mkv/0,streams=0 id=mkv/1,streams=1" \
-f dash -dash 1 out.mpd

Antworten (1)

Wann ffmpeg zur Ausgabe gelöscht wird, hängt vom Protokoll ab. Für das Dateiprotokoll müssen mindestens 256 KB Daten warten, es sei denn, die Ausgabe ist beendet. Für Textformate gibt es also nur einen Payload-Schreibvorgang.

Sie können dies umgehen, indem Sie ffmpeg zwingen, nach jedem Paket einen Stream zu leeren.

 ffmpeg -nostdin -i - -map 0:2 -c:0 webvtt -flush_packets 1 -f webvtt first.vtt \
-map 0:3 -c:0 webvtt -flush_packets 1 -f webvtt second.vtt \
-map 0:0 -c:0 copy -map 0:1 -c:1 aac \
-use_timeline 1 -min_seg_duration 1000000 \
-use_template 1 -init_seg_name $RepresentationID$-0.mp4s \
-media_seg_name $RepresentationID$-$Number$.mp4s \
-adaptation_sets "id=mkv/0,streams=0 id=mkv/1,streams=1" \
-f dash -dash 1 out.mpd
Siehe auch stackoverflow.com/questions/50574086/… für ein weiteres Beispiel