Der ffmpeg concat-Filter fügt die Audio-Verzögerung allmählich hinzu

460
Mr.Clowder

Ich verwende ffmpeg, um viele Videodateien mithilfe von filter_complex zu verketten. Allerdings hat die Ergebnisdatei seine Audio out of sync allmählich .

und ich benutze mediainfo --Inform='Video;%Duration%' filename.extund mediainfo --Inform='Audio;%Duration%' filename.ext, um die Dauerzahl im folgenden Prozess anzuzeigen.

So erstellen Sie mein Problem anhand einer Original-Quelldatei erneut:

Stream #0:0(eng): Video: wmv3 (Main) (WMV3 / 0x33564D57), yuv420p, 1920x1080, 6000 kb/s, 29.97 fps, 29.97 tbr, 1k tbn, 1k tbc Stream #0:1(eng): Audio: wmav2 (a[1][0][0] / 0x0161), 48000 Hz, stereo, fltp, 128 kb/s 

Die Größe ist zu groß, aber die Video- und Audiospuren haben dieselbe Dauer wie XXXXXXX ms, die von mediainfo gemeldet wird

zu Testzwecken benutze ich die ersten 5 Sekunden mit doppeltem "-t 5" :

ffmpeg -t 5 -i input.wmv -map 0:v:0 -map 0:a:0 -map_chapters -1 \ -vcodec copy -acodec copy -t 5 source_v5a5.mkv 

Ergebnisdauer (ms):

5004.000000 video of source_v5a5.mkv 5119.000000 audio of source_v5a5.mkv 

der Unterschied ist 119-4 = 115ms und mediainfo filename.extmeldet nichts über die Verzögerung in diesem Moment. Dieses Snippet spielt gut, wenn ich es sehe, möglicherweise mit einer Verzögerung von 115ms (im Kopf?), was nicht so auffällt

[vvvvvvvvv………………v] [-aaaaaaaaa………………a] 

Kopieren Sie diese Datei jetzt dreimal, wobei wir vorgeben, dass wir viele verschiedene Ausschnitte haben, und kodieren Sie Video- und Audiospuren separat:

ffmpeg -i source_v5a5_p1.mkv -i source_v5a5_p2.mkv -i source_v5a5_p3.mkv -i source_v5a5_p4.mkv \ -filter_complex " \ [0:v:0]setpts=PTS-STARTPTS[v0];[0:a:0]asetpts=PTS-STARTPTS[a0]; \ [1:v:0]setpts=PTS-STARTPTS[v1];[1:a:0]asetpts=PTS-STARTPTS[a1]; \ [2:v:0]setpts=PTS-STARTPTS[v2];[2:a:0]asetpts=PTS-STARTPTS[a2]; \ [3:v:0]setpts=PTS-STARTPTS[v3];[3:a:0]asetpts=PTS-STARTPTS[a3]; \ [v0][a0][v1][a1][v2][a2][v3][a3] concat=n=4:v=1:a=1 [out]" \ -map "[out]" \ -vsync vfr -vcodec libx264 -preset veryfast -tune film -crf 23 \ -acodec pcm_s16le -f tee "[select=v:f=mp4]output_video_track.mp4" 

ja, ich füge hier acodec hinzu, aber nur videostream. Kodiere jetzt Audio, Pipe-ffmpeg-Ausgabe an NeroAAC :

ffmpeg -i source_v5a5_p1.mkv -i source_v5a5_p2.mkv -i source_v5a5_p3.mkv -i source_v5a5_p4.mkv \ -filter_complex " \ [0:v:0]setpts=PTS-STARTPTS[v0];[0:a:0]asetpts=PTS-STARTPTS[a0]; \ [1:v:0]setpts=PTS-STARTPTS[v1];[1:a:0]asetpts=PTS-STARTPTS[a1]; \ [2:v:0]setpts=PTS-STARTPTS[v2];[2:a:0]asetpts=PTS-STARTPTS[a2]; \ [3:v:0]setpts=PTS-STARTPTS[v3];[3:a:0]asetpts=PTS-STARTPTS[a3]; \ [v0][a0][v1][a1][v2][a2][v3][a3] concat=n=4:v=1:a=1 [out]" \ -map "[out]" \ -vcodec rawvideo \ -acodec pcm_f32le -f tee "[select=a:f=wav]pipe\:"|neroAacEnc -ignorelength \ -q 0.2 -if - -of "output_audio_track.m4a" 

ja, ich füge hier vcodec hinzu, aber nur Audiostream.

Ergebnisdauer (ms):

20020 output_video_track.mp4 20309 output_audio_track.m4a 20069.000000 video stream of output_MkvMergeMuxed.mkv 20310.000000 audio stream of output_MkvMergeMuxed.mkv 

der Unterschied ist über 200 ms, scheint die Verzögerung während des concat enthalten zu sein? Beim Abspielen der Multiplex-Datei ist es zunächst in Ordnung, aber beim letzten Teil würde ich die Verzögerung spüren

unter der Annahme, dass die Verzögerung im Kopf ist, zieht es wie folgt:

[v111111v222222v333333v444444] [-a111111-a222222-a333333-a444444] 

wie in der Dokumentation beschrieben: https://ffmpeg.org/ffmpeg-filters.html#concat

Der Concat-Filter verwendet die Dauer des längsten Streams in jedem Segment (außer dem letzten) und füllt ggf. kürzere Audiostreams mit Stille aus.

Ich habe den Verdacht, dass mein Test nicht genug ist. Ich habe den gesamten Vorgang erneut mit source_ v5a2 .mkv und erneut mit source_ v5a10 .mkv durchgeführt

Dauer:

5004.000000 video of source_v5a2.mkv 2279.000000 audio of source_v5a2.mkv 5004.000000 video of source_v5a10.mkv 10281.000000 audio of source_v5a10.mkv 

ffmpeg tat dies wie in der Dokumentation (Silence aufgefüllt, als ob ein Apad angewendet wurde / letzter Frame eingefroren wurde), aber das Ergebnis bleibt ungefähr gleich: erkennbare Verzögerung zu Beginn des letzten Segments

[v111111v222222v333333v444444] [-a111___-a222___-a333___-a444] 

und

[v111___v222___v333___v444___] [-a111111-a222222-a333333-a444444] 

Der obige Test enthält nur 4 Dateien . Wenn Sie mehr als 50 Dateien zusammenstellen, ist die Synchronisierung von Bedeutung, die Sie nicht ignorieren können


Frage:

Angesichts einer Reihe von Videodateien ( 50+, Video-Audio dieselben res / codec / track # / etc, gleiche Dauer meistens, manche nicht), um zu konstatieren, wie die Verzögerung verringert / vermieden werden kann, um die Synchronisierung vorzunehmen, ohne das Video mit schwarzem Bildschirm aufzufüllen ? mögen

[v111111v222222v333333v444444] [-a111111a222222a333333a444444] 

oder noch besser, wenn die Verzögerung abgeschnitten ist (vielleicht kann mkvmerge dies mit ein paar Berechnungen erledigen.)

[v111111v222222v333333v444444] [a111111a222222a333333a444444] 

Es ist besser, wenn keine Zwischendateien erstellt werden, das Piping ist in Ordnung


Aktualisieren:

Vielleicht habe ich alles falsch verstanden. Vielleicht ist es keine Verzögerung, sondern ein "Stretch / Squeeze". Ich habe einen langen Test mit 30 WMV-Dateien durchgeführt. Mit dem Befehl wie oben erhielt ich das Ergebnis Datei A mit über 1s Desync:

Stream #0:0: Video: h264 (High), yuv420p(progressive), 640x480 [SAR 4:3 DAR 4:3], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default) Metadata: DURATION-eng : 05:32:10.544000000 NUMBER_OF_FRAMES-eng: 597298 Stream #0:1: Audio: aac (HE-AAC), 48000 Hz, stereo, fltp (default) Metadata: DURATION-eng : 05:32:11.861000000 NUMBER_OF_FRAMES-eng: 467153 

aresample=async=1Danach füge ich den Filter vor asetpts hinzu und codiere erneut in Datei B :

Stream #0:0: Video: h264 (High), yuv420p(progressive), 640x480 [SAR 4:3 DAR 4:3], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default) Metadata: DURATION-eng : 05:32:11.727000000 NUMBER_OF_FRAMES-eng: 597298 Stream #0:1: Audio: aac (HE-AAC), 48000 Hz, stereo, fltp (default) Metadata: DURATION-eng : 05:32:11.862000000 NUMBER_OF_FRAMES-eng: 467153 

Datei A hat auch das Synchronisierungsproblem, aber Datei B synchronisiert gut! Das, aresample=async=1was für das Audio gilt, wirkt sich also nicht auf das Audio aus, sondern auf das Video! Ich denke, es hat etwas mit dem PTS zu tun. Nach einigem Googeln habe ich folgendes Exp A gemacht :

  1. konvertiere 05: 32: 10.544000000 und 05: 32: 11.727000000 in 19930544 und 19931727
  2. Ziehen Sie mit mkvmerge in Datei A und fügen Sie 19931727/19930544 in das Feld " Stretch By " der Videospur ein, Start Muxing

die Ergebnisdatei-Synchronisierung in Ordnung (vielleicht kein auffälliges Desync), scheint das Synchronisierungsproblem etwas mit PTS zu tun zu haben? Weitere Forschungen, sagen wir, die korrekte Synchronisierungsdatei hat eine längere Dauer, während die Desynchronisierungsdatei eine kürzere Dauer hat. Ich habe folgendes Exp B ausgeführt :

  1. Verwenden Sie mediainfo --Inform='General;%Duration%' filename.extdiese Option, um die Dauer jeder Datei abzurufen
  2. addiere jede Dauerzahl

Die Gesamtdauer beträgt 05: 32: 10.438, fast die kürzere Dauer

Neue Fragen:

  1. Haben meine ersten Befehle "Richtiges PTS, längeres Audio" oder "Gedrücktes PTS, Korrektes Audio" erzeugt?
  2. Wenn es "Richtiges PTS, längeres Audio" ist, wie kann ich das Audio korrigieren?
  3. Wenn es "Squeezed PTS, Correct Audio" ist, verwendet es aresample=async=1 die richtige Methode, um PTS zu korrigieren, während Videos von Grund auf neu erstellt werden ?
  4. Wenn es sich um "Quetschendes PTS, Correct Audio" handelt, warum zeigt mein Exp B, dass die Gesamtdauer sehr nahe an dem kürzeren (quetschten) ist?
  5. Wenn Exp B falsch ist, wie sollte ich die korrekte Gesamtdauer vor dem Kodierungsprozess vorhersagen / berechnen?
  6. Kann ich das Synchronisierungsproblem beheben, indem ich die Datei "Squeezed PTS, Correct Audio" ohne die Quelldatei mit der Zahl "AudioDuration / VideoDuration" strecke / drückte?
  7. Wenn keine Dateien zusammengefügt werden müssen, sondern nur eine einzelne Datei kodiert, ist es erforderlich aresample=async=1, hinzugefügt zu werden, wenn NO vf oder af verwendet wird. Notwendig, wenn vf oder af verwendet wird? Irgendein Nachteil?

Es ist ein langer Text oben, auch wenn Sie nicht antworten konnten, danke, dass Sie bis zum Ende gelesen haben. :)

2

0 Antworten auf die Frage