Starten Sie den ffmpeg-Job nach einem Fehler neu

Gibt es eine gängige Technik oder eine Art Strategie, um einen fehlgeschlagenen Transcodierungsauftrag dort neu zu starten, wo er beim Absturz aufgehört hat (oder aus irgendeinem Grund angehalten wurde)?

Wenn ich zum Beispiel einen 2-stündigen Transcodierungsjob habe und er nach 1 Stunde und 59 Minuten fehlschlägt/abstürzt, gibt es eine Möglichkeit, einfach die Arbeit der letzten Minuten zu erledigen und den Fortschritt zu nutzen, den ich bereits hatte, vorausgesetzt, die teilweise transcodierte Datei ist noch verfügbar?

Antworten (2)

Eine direkte Option zum Fortsetzen der Codierung ist nicht verfügbar.

Und das manuelle Neustarten der Codierung ist ebenfalls nicht möglich. Zwei Gründe:

1) Beim Umcodieren in einen typischen Container wie MP4 wird der Index geschrieben, nachdem die Codierung abgeschlossen ist. Es gibt keinen solchen Index in einer Teildatei, wenn der Prozess unerwartet beendet wurde, und daher kann die vorhandene Datei nicht analysiert werden.

2) Wenn Sie den letzten unbeschädigten Frame, der in der Teildatei codiert ist, nicht genau identifizieren können, wird Ihre Verbindung nicht nahtlos sein.


Das heißt, es gibt einen mühsamen Weg, dies zu tun. Das Verfahren hängt von der Verwendung des segmentMuxers ab. Sie codieren in das MPEG-TS-Format, aber segmentieren die Ausgabe, während sie generiert wird. Sollte der Job fehlschlagen, untersuchen Sie einige Attribute und setzen die Codierung basierend auf diesen Daten fort. Schließlich fügen Sie alle Segmente zusammen.

Schritt 1 : Kodieren und segmentieren

Für beste Ergebnisse sollten Audio und Video separat erstellt werden. Tatsächlich kann das Audio ohne Segmentierung erstellt werden, da es viel schneller codiert wird

ffmpeg -i in.mp4 -c:a aac -vn job-audio.mp4

Und für Videos

ffmpeg -copyts -start_at_zero -ss 0 -i in.mp4 -c:v libx264 -an
       -f segment -segment_time 0.01 -segment_time_delta 1
       -muxpreload 0 -muxdelay 0 -mpegts_copyts 1
       -segment_start_number 0 -segment_list files.ffcat
job-video%d.ts

Jedes obige Segment enthält eine GOP, sodass keine Frames in einem Segment für die Wiedergabe auf Frames in anderen Segmenten angewiesen sind.

Schritt 2 Identifizieren Sie den Wiederaufnahmepunkt

Angenommen, der Job schlägt beim Erstellen von Segment Nr. 5 fehl.

Zuerst rennst du

ffprobe "in.mp4" -show_entries stream=codec_type,start_time,duration -of compact

Dies wird eine Anzeige wie diese erzeugen

stream|codec_type=audio|start_time=0.000000|duration=356.309333
stream|codec_type=video|start_time=0.040000|duration=356.360000

Beachten Sie die Startzeit für den Videostream.

Führen Sie es nun für das erste und das letzte (unvollständige) Segment aus

ffprobe "job-video0.ts" -show_entries stream=codec_type,start_time,duration -of compact

stream|codec_type=video|start_time=0.080000|duration=10.000000

Sie sehen, dass es einen positiven Offset von 0,04 bezüglich des MP4-Videostreams gibt. Nennen wir dies den anfänglichen Offset-Wert

Nun zum letzten Stream

ffprobe "job-video5.ts" -show_entries stream=codec_type,start_time,duration -of compact

stream|codec_type=video|start_time=20.080000|duration=4.320000

Schritt 3 Setzen Sie die Codierung fort

Also, jetzt rennst du

ffmpeg -copyts -start_at_zero -ss {start_time of last segment - initial offset} -i in.mp4 -c:v libx264 -an
       -f segment -segment_time 0.01 -segment_time_delta 1
       -muxpreload 0 -muxdelay 0 -mpegts_copyts 1 -initial_offset {initial offset}
       -segment_start_number {index number of last segment} -segment_list files-resume.ffcat
job-video%d.ts

Schritt 4 Segmente verbinden

Sie haben mehrere .ffcatDateien – von der ersten Ausführung und allen fortgesetzten Ausführungen. Kopieren Sie die Einträge aus allen sekundären Läufen und hängen Sie sie an die erste Datei an. Vermeide Dopplungen.

Laufen

ffmpeg -f concat -i files.ffcat -i job-audio.mp4 -c copy full.mp4
Wissen Sie zur Verdeutlichung, dass es eine GOP pro Segment geben wird, da, wie es in den Dokumenten heißt, wenn segment_time_delta "... angegeben ist, ein Schlüsselbild ein neues Segment beginnt, wenn sein PTS die Beziehung erfüllt ..."?
Ja, die sehr niedrige segment_time sorgt dafür, dass das Delta selten ins Spiel kommt. Ich habe diese Option ursprünglich hinzugefügt, weil meine ursprünglichen Befehle auch Audio enthielten. Und das Format start_time ist in diesen Fällen nicht immer dasselbe wie die start_time des Videos. Jetzt ist es strittig.

Wenn Sie den spezifischen Teil der Datei kennen, an dem der Codierungsjob blockiert, können Sie die Optionen und verwenden ffmpeg, um den Choke-Punkt zu umgehen. Weitere Informationen zu diesen Optionen finden Sie in der Dokumentation des Tools .--ss-t

Nehmen wir an, der Ausfall ist unvorhersehbar, dh es gibt keinen bekannten Ausfallpunkt.