FFMPEG-Audio ist beim Transkodieren (Demuxen) von DV nicht synchron

12636
Wojciech

Ich bin seit Monaten mit diesem Problem beschäftigt. Ich habe über 50 DV-Bänder (von und alten Sony-Camcordern), die in ein moderneres, brauchbareres Format (höchstwahrscheinlich H264) umgewandelt werden können. Ich habe damit angefangen, die Dateien mit DVGRAB auf meinen PC zu laden (über Firewire). Dort hatte ich zwei Möglichkeiten: RAW-Daten von der DV-Kassette abziehen, eine Multiplex-Datei erzeugen oder sie demuxen und in eine DVI-Datei speichern.

Dort begannen die Probleme. Das Speichern in einer DVI-Datei führte dazu, dass das Audio nicht synchron war. Ich dachte, es ist ein Problem mit DVGRAB, also habe ich die RAW-Dateien gespeichert (die korrekt synchronisiert wurden) und wollte sie mit ffmpeg verarbeiten.

Es stellt sich heraus, dass das Audio, egal wie ich es demuxe, immer nicht synchron ist. Bevor Sie etwas zur Abtastfrequenz sagen - die Audio-Unterschiede sind absolut zufällig. Ein stundenlanges Band kann am Ende zwischen 0,1 und 4 Sekunden Audio-Verzögerung haben.

Hier ist eine Beispieldatei, die ich in separate Audio- und Videodateien aufgeteilt habe, um die Unterschiede zu überprüfen.

# ffprobe -i ./video_conversion/13.dv  ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers built with gcc 5.3.0 (GCC) configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab libavutil 54. 31.100 / 54. 31.100 libavcodec 56. 60.100 / 56. 60.100 libavformat 56. 40.101 / 56. 40.101 libavdevice 56. 4.100 / 56. 4.100 libavfilter 5. 40.101 / 5. 40.101 libavresample 2. 1. 0 / 2. 1. 0 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 2.101 / 1. 2.101 libpostproc 53. 3.100 / 53. 3.100 [dv @ 0x864f2a0] Detected timecode is invalid [dv @ 0x864f2a0] Estimating duration from bitrate, this may be inaccurate Input #0, dv, from './video_conversion/13.dv': Duration: 01:00:45.80, start: 0.000000, bitrate: 28800 kb/s Stream #0:0: Video: dvvideo, yuv420p, 720x576 [SAR 16:15 DAR 4:3], 28800 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc Stream #0:1: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s  # ffprobe -i ./video_conversion/tmp/13.mp4 ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers built with gcc 5.3.0 (GCC) configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab libavutil 54. 31.100 / 54. 31.100 libavcodec 56. 60.100 / 56. 60.100 libavformat 56. 40.101 / 56. 40.101 libavdevice 56. 4.100 / 56. 4.100 libavfilter 5. 40.101 / 5. 40.101 libavresample 2. 1. 0 / 2. 1. 0 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 2.101 / 1. 2.101 libpostproc 53. 3.100 / 53. 3.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './video_conversion/tmp/13.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf56.40.101 Duration: 01:00:45.80, start: 0.000000, bitrate: 5685 kb/s Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 720x576 [SAR 16:15 DAR 4:3], 5683 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: handler_name : VideoHandler  # ffprobe -i ./video_conversion/tmp/13.mp3 ffprobe version 2.8.4 Copyright (c) 2007-2015 the FFmpeg developers built with gcc 5.3.0 (GCC) configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab libavutil 54. 31.100 / 54. 31.100 libavcodec 56. 60.100 / 56. 60.100 libavformat 56. 40.101 / 56. 40.101 libavdevice 56. 4.100 / 56. 4.100 libavfilter 5. 40.101 / 5. 40.101 libavresample 2. 1. 0 / 2. 1. 0 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 2.101 / 1. 2.101 libpostproc 53. 3.100 / 53. 3.100 [mp3 @ 0x954c2a0] Skipping 0 bytes of junk at 237. Input #0, mp3, from './video_conversion/tmp/13.mp3': Metadata: encoder : Lavf56.40.101 Duration: 01:00:44.35, start: 0.023021, bitrate: 128 kb/s Stream #0:0: Audio: mp3, 48000 Hz, stereo, s16p, 128 kb/s Metadata: encoder : Lavc56.60 

Diese bestimmte unterscheidet sich um 1,448 Sekunden. Wie gesagt, die Unterschiede sind sehr unterschiedlich.

Wie für die Lösung. Ich könnte das Audio einfach strecken und mit dem Video kombinieren (ich habe das getestet), aber ich kann nicht sicher sein, ob das Audio irgendwo in der Mitte der Aufnahme synchron ist.

Ich glaube, ich habe die Ursache dieses Verhaltens herausgefunden. Immer, wenn ich die Kamera ein- oder ausschalte (um die Aufnahme zu starten und zu stoppen), beginnt das Video nur ein kleines bisschen schneller als der Ton. Je mehr "Fragmente" sich auf dem Band befinden, desto mehr addieren sich diese Unterschiede.

Wie kann ich das beheben? Gibt es eine Möglichkeit, Audio und Video mit Zeitstempeln zu demuxen, damit sie sich nach der Konvertierung korrekt addieren? Oder gibt es diese Lücken im Audio trotzdem zu füllen, damit beide Streams gleich groß sind?

2
Wie lautet der Befehl, die Rohdateien zu demuxen? Gyan vor 8 Jahren 0
Die unformatierte .dv-Datei wird von Natur aus gemultiplext. FFMPEG demuxiert es standardmäßig, wenn es in einen beliebigen Container konvertiert wird. Wojciech vor 8 Jahren 0
Ok, was ist dein Konvertierungsbefehl? Ich habe vergessen, dass du transkodierst. Gyan vor 8 Jahren 0
Ich habe ein Dutzend Kombinationen ausprobiert. Nichts Besonderes: avconv -f dv -i ./46raw.dv -f mp4 -acodec libvo_aacenc -b: ein 256k -vcodec libx264 -b: v 4000k -y ./46raw.aac.mp4 Wojciech vor 8 Jahren 0
avconv! = ffmpeg. Wenn es sich nur um ein Offset-Problem handelt, können Sie `-af adelay = 1000 | 1000` verwenden, wobei 1000 Verzögerung in ms ist. Gyan vor 8 Jahren 1
Tippfehler. Ich benutze ffmpeg auf einem Rechner und avconv auf dem anderen. So oder so funktioniert es nicht. Wenn es eine Versatzverzögerung wäre, würde ich diese Frage nicht stellen. Es ist ein Längenunterschied der Audiospur von etwa 0,1 bis 4 Sekunden bei einem 3600-3700s langen Video. Wojciech vor 8 Jahren 0
Fügen Sie als Ausgabe-Flag "-copyts" hinzu und versuchen Sie es. Überprüfen Sie in der Wiedergabe nach der Synchronisation und nicht nach der Dauer, da dieses Flag den Ton nicht anpasst, um die Dauer auszugleichen. Wenn Sie keine ältere Version als Dec '15 verwenden, ist der interne AAC-Encoder jetzt stabil und besser als der VO-Encoder. Gyan vor 8 Jahren 0
Zwei Dateien mit und ohne Kopien erstellt. Kein Unterschied. Immer noch zurückhaltend. :( Irgendwelche anderen Ideen? Wojciech vor 8 Jahren 0
Die RAW-Dateien haben eine gute Synchronisierung, richtig? Wie spielst du das? Gyan vor 8 Jahren 0
Die Rohdateien sind natürlich gut. Wenn das schlecht wäre, würde meine Frage keinen Sinn ergeben. In mplayer gespielt, funktionieren sie gut. Jeder Versuch, die Audio- und Videoströme zu demuxen, auch eine "Kopie", und sie in einen beliebigen Container zurückzusetzen, führt dazu, dass sie nicht synchron sind. Der Fehler wird entlang der Videolänge größer und erreicht am Ende die 0,1-4s-Verschiebung. Wojciech vor 8 Jahren 0
Wickeln Sie das RAW in eine AVI-Datei und überprüfen Sie Folgendes: `ffmpeg -f dv -i ./46raw.dv -c kopiert -map 0 -y. / 46raw.avi` Gyan vor 8 Jahren 0
Ich wollte sofort antworten, aber aus Gründen der Integrität habe ich es geprüft. Entschuldigung ... noch nicht synchron. Das Problem liegt im Demuxieren der Streams. Wojciech vor 8 Jahren 0
Können Sie die ersten 10 Sekunden des Rohbilds abschneiden und teilen? Sie müssen "dd" oder so ähnlich verwenden. Gyan vor 8 Jahren 0
Außerdem sieht es so aus, als würde der DV-Demuxer bei fehlendem oder schlechtem Audio nicht gut abgespielt. Schreiben Sie eine Zeile an @rhatr auf Twitter. Er ist einer der Codierer des DV-Demuxer-Codes. Gyan vor 8 Jahren 0
Nun ... Das sind Familienvideos meiner Schwester, daher fühle ich mich nicht wirklich gut, wenn ich sie teilen möchte. Vielleicht finde ich ein neutrales Fragment. Danke, dass Sie mich auf einen der Entwickler aufmerksam gemacht haben. Ich benutze kein Twitter, aber ich denke ich muss. Wojciech vor 8 Jahren 0
Hast du Fortschritte gemacht? Gyan vor 8 Jahren 0
Ich habe Roman (@rhatr) kontaktiert und ihm eine Probe des Videos geschickt. Er kämpfte mehr als eine Woche damit, aber ohne Erfolg :( Ich bin wirklich dankbar für die angebotene Zeit, aber das bedeutet, dass die Angelegenheit kompliziert ist: / Ich werde versuchen zu prüfen, ob andere Videobearbeitungsprogramme damit umgehen können. Wojciech vor 8 Jahren 0

3 Antworten auf die Frage

6
Gyan

Hier sind drei Wildcard-Versuche zur Lösung dieses Problems:

Methode 1a Verwenden Sie die Systemzeit als Zeitstempel

ffmpeg -use_wallclock_as_timestamps 1 -i input.dv \ -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -fflags +genpts method1.ts 

Methode 1b Verwenden Sie Resampler mit gesetztem Flag, um die Stille einzuschalten, wenn die Zeitstempel der Eingabe-Audio-Dateien Lücken aufweisen

ffmpeg -i input.dv -c:v libx264 -b:v 4000k \ -af "aresample=async=1:first_pts=0" -c:a aac -b:a 128k -fflags +genpts method1.ts 

Methode 2 Mit Dummy-Audio zusammenführen

ffmpeg -i input.dv -f lavfi -i "aevalsrc=0:c=2:s=48000" \ -filter_complex "[0:a][1:a]amerge[a]" -map 0:v -map "[a]" -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -ac 2 -shortest method2.ts 

Methode 3 Kombination der oben genannten

ffmpeg -use_wallclock_as_timestamps 1 -i input.dv -f lavfi -use_wallclock_as_timestamps 1 -i "aevalsrc=0:c=2:s=48000" \ -filter_complex "[0:a][1:a]amerge[a]" -map 0:v -map "[a]" -c:v libx264 -b:v 4000k -c:a aac -b:a 128k -ac 2 -shortest method3.ts 

Sie können jeden von ihnen für kurze Zeit testen, indem Sie -t Nz. B. -t 20einen Test von 20 Sekunden einfügen .

Wenn einer von ihnen funktioniert, können wir die Ausgabe als MP4 umschließen.

Option 2: Es wurde erwartet, dass der einfache Filtergraph 'amerge' genau 1 Eingang und 1 Ausgang hat. Es hatte jedoch> 1 Eingang (e) und 1 Ausgang (en). Bitte passen Sie an oder verwenden Sie stattdessen eine komplexe Filtergrafik (-filter_complex). Option 1. Gibt viele Fehler aus: [aac @ 0x9160040] Warteschlangeneingabe ist in der Zeit rückwärts [mp4 @ 0x915e1c0] Nicht monotoner DTS im Ausgabestrom 0: 1; vorher: 70000289337917, aktuell: 70000289337250; Änderung in 70000289337918. Dies kann zu falschen Zeitstempeln in der Ausgabedatei führen. Und stoppt nach ca. 90 MB einer nicht abspielbaren Ausgabedatei. Wojciech vor 8 Jahren 0
Versuchen Sie jetzt die 3 Befehle. Testen Sie auch die Wiedergabe mit ffplay, dh `ffplay method1.ts` Gyan vor 8 Jahren 0
Die Optionen 1a und 3 erzeugen 90 MB bzw. 20 MB Dateien mit wenig bis gar keinem Video. Die Optionen 1b und 2 produzieren das gesamte Video, helfen aber nicht bei der Verzögerung :( Wojciech vor 8 Jahren 0
Das blind zu machen ist sinnlos. Können Sie ein bisschen der Rohdatei senden, etwa 20 Sekunden, oder genug, um einen Synchronisationsverlust mit Ihrem ursprünglichen Befehl zu beobachten? Gyan vor 8 Jahren 0
0
Wojciech

I've finally solved the issue - it's an overkill, but it works.

I've realized that if I copy the .dv to any other container, the audio and video is obviously out of sync. Then I wanted to cut that file to a 1 minute segment starting at the 51st minute (-ss 51:00 -t 60), it was obviously still out of sync.

However, when I used the same cut (-ss 51:00 -t 60) on the original .dv it was in sync! So what I ended up doing is I wrote a script that cut the .dv file into 1 second segment every second and saved that into separate files (yes over 3600 files per .dv). No encoding, just stream copy to a new container (avi). Then I used -f concat, to put the tiny files into one avi file, that was in sync now! Any gaps are inaudible! All that was left was encoding H264 and AAC into MP4.

I ran the script on my home server that was grinding the 50 .dv files for a couple of days, but now it's done!

THANK YOU ALL FOR YOU HELP! I've learned a lot about ffmpeg and a/v in general.

Dies ist eine gute Lösung, löst das Synchronisierungsproblem jedoch nicht wirklich, da bei jedem DV-zu-AVI-Wrapping derselbe Fehler auftritt, den Sie beim Kopieren der gesamten .dv-Datei in .avi hatten. Diese Problemumgehung besteht darin, zu verhindern, dass winzige Abweichungen in jedem 1-Sekunden-Segment kaskadiert und akkumuliert werden, da jede Sekunde eine separate Datei ist. Es gibt immer noch ein paar AVIs, bei denen Async erkennbar ist, diese betreffen jedoch nicht die verbleibenden AVI-Segmente. Wenn Sie können, bin ich immer noch offen für die Bearbeitung eines kurzen Abschnitts des rohen .dv, um zu sehen, ob dies in einem Schritt genau gelöst werden kann. Gyan vor 8 Jahren 0
Ich bin mir bewusst, dass die Lücken immer noch vorhanden sind, aber das Ausdehnen der Audiodaten wäre die gleiche Lösung. Das ist gut genug für mich. Über die Probe - es ist wenig sinnvoll, eine kleine Probe zu senden, da der Fehler in 1h höchstens 3s beträgt und weniger als 0,1% beträgt. Ich kann Ihnen keine vollständige Datei senden, da dies die Familienvideos meiner Schwester sind (sie würde nicht zustimmen). Wenn ich ein leeres Band bekomme, könnte ich ein neues Sample für Sie erstellen, mit dem Sie arbeiten können (Filmaufnahmen auf einem Fernsehgerät würden Ihnen eine gute Synchronisationsreferenz geben). Wojciech vor 8 Jahren 0
Meine gewünschte Lösung beinhaltet kein Stretching von Audio. Raw DV hat keine Zeitstempel, aber das Audio ist synchron verschachtelt, so dass mein Basteln darauf abzielt, diese chronologische Beziehung zu bewahren. Wenn Sie jemals die Zeit haben, bin ich bereit, mit einem Sample zu arbeiten. Gyan vor 8 Jahren 0
0
Noeljunior

Ich habe ein ähnliches Setup mit dem gleichen Audio-Synchronisationsproblem. Es ist mir auch gelungen, einen Clip mit nicht synchronisiertem Audio wiederzugeben. Wenn jemand Proben möchte, fragen Sie bitte.

Ich habe möglicherweise eine Lösung für dieses Problem gefunden. Kino ist eine sehr alte und nicht mehr gewartete Software, die die Fähigkeit besitzt, eine .dv-Datei von dvgrab (raw) zu laden und erneut als .dv- oder dv1 / avi-Datei (oder dv2 / avi) -Datei mit "Re-Sampling" des Audiomaterials zu exportieren . Nun, die Ausgabe ist eine korrigierte Datei, die vor und nach einem 'ffmpeg'-Transcode gut synchronisiert wird.

Es gibt einige Nachteile. Das Kino kann aufhören zu arbeiten oder funktioniert überhaupt nicht, da es alt ist. Ich habe es gerade von 'aur' (Arch linux) installiert und konnte es unkompliziert verwenden. Es gibt keine Befehlszeilenschnittstelle. Ich konnte keinen Weg finden, dies zu automatisieren.

BEARBEITEN:

Möglicherweise gibt es eine andere Lösung. Ich denke, das Problem ist, dass die Start- und Stop-Bits des Streams irgendwie beschädigt werden und der Timecode schlechter wird. Ich habe einige Clips, die ein Datum aus dem Jahr '2068' zu haben scheinen. Auf jeden Fall können Sie das 'dvgrab' erneut verwenden, um die Clips jedes Mal zu teilen, wenn Sie glauben, dass es einen neuen Aufnahmestream gibt:

dvgrab -I input -size 0 -a -format=raw -showstatus -srt -t output 

'-a' unterstützt die automatische Aufteilung, '-srt' und '-t' helfen beim Verfolgen der Dateien (erstellt eine srt mit den Datumsangaben und hängt das Datum jeweils an die Dateien an). Dadurch wird für jeden neuen Stream eine neue Datei erstellt . Da der Anfang jedes Streams synchron ist, können Sie ihn einzeln "ffmpeg". Es scheint, dass jede Datei den Timecode der ursprünglichen "Sitzung" enthält (wie dvgrab es nennt). Wenn Sie also alle Dateien direkt mit ffmpeg speichern, werden Sie immer noch nicht synchronisiert.