Wie lassen sich Video- und Audio-Timecodes bei Null beginnen?

1364
siods333333

Diese Frage erfordert wahrscheinlich die Kenntnis des Matroska-Formats. Wenn ich Video und Audio zusammen muxiere, beginnen Audiopakete mit Timecode 0 und Video mit Timecode 7. Sollte ein 30-fps-Video mit Timecode 0 oder mit Timecode 33 beginnen (für Zeit 0,033 sind Timecodes in Millisekunden)? Kann ich es so machen, dass sowohl Audio als auch Video mit Timecode 0 beginnen?

Sie müssen nicht weiter unten lesen, der Rest ist nur eine Zusatzinformation.


Ich habe versucht, Filter [v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a]als die beiden letzten Filter hinzuzufügen, aber es hat sich nichts geändert.

Hier ist der vollständige Befehl, den ich benutze. Es ist nur eine Vp8-Kodierung mit zwei Durchläufen für Video und eine Opus-Kodierung mit Durchlauf für Audio. Es schneidet auch ein Video in einige 3 Sekunden lange Stücke und fügt sie zusammen.

ffmpeg -threads 1 -i 480P_600K_71149981.mp4 -force_key_frames 00:00:03.000 -filter_complex [0:v]scale=320x180:force_original_aspect_ratio=decrease,fps=30[vid];[vid]split[vid][vid_copy];[vid_copy]trim=start=0:duration=3,setpts=PTS-STARTPTS[c0v];[0:a]atrim=start=0:duration=3,asetpts=PTS-STARTPTS[c0a];[vid]split[vid][vid_copy];[vid_copy]trim=start=90:duration=3,setpts=PTS-STARTPTS[c1v];[0:a]atrim=start=90:duration=3,asetpts=PTS-STARTPTS[c1a];[vid]split[vid][vid_copy];[vid_copy]trim=start=180:duration=3,setpts=PTS-STARTPTS[c2v];[0:a]atrim=start=180:duration=3,asetpts=PTS-STARTPTS[c2a];[vid]trim=start=270:duration=3,setpts=PTS-STARTPTS[c3v];[0:a]atrim=start=270:duration=3,asetpts=PTS-STARTPTS[c3a];[c0v][c0a][c1v][c1a][c2v][c2a][c3v][c3a]concat=n=4:v=1:a=1[v][a];[v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a] -map [v] -map [a] -c:v vp8 -b:v 200k -crf 54 -profile:v 1 -an -pass 1 -passlogfile jump_passlogfile -f null NUL   ffmpeg -threads 1 -i 480P_600K_71149981.mp4 -force_key_frames 00:00:03.000 -filter_complex [0:v]scale=320x180:force_original_aspect_ratio=decrease,fps=30[vid];[vid]split[vid][vid_copy];[vid_copy]trim=start=0:duration=3,setpts=PTS-STARTPTS[c0v];[0:a]atrim=start=0:duration=3,asetpts=PTS-STARTPTS[c0a];[vid]split[vid][vid_copy];[vid_copy]trim=start=90:duration=3,setpts=PTS-STARTPTS[c1v];[0:a]atrim=start=90:duration=3,asetpts=PTS-STARTPTS[c1a];[vid]split[vid][vid_copy];[vid_copy]trim=start=180:duration=3,setpts=PTS-STARTPTS[c2v];[0:a]atrim=start=180:duration=3,asetpts=PTS-STARTPTS[c2a];[vid]trim=start=270:duration=3,setpts=PTS-STARTPTS[c3v];[0:a]atrim=start=270:duration=3,asetpts=PTS-STARTPTS[c3a];[c0v][c0a][c1v][c1a][c2v][c2a][c3v][c3a]concat=n=4:v=1:a=1[v][a];[v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a] -map [v] -map [a] -c:v vp8 -b:v 200k -crf 54 -profile:v 1 -c:a libopus -b:a 32k -vbr on -compression_level 7 -ac 1 -ar 48000 -pass 2 -passlogfile jump_passlogfile -f webm -reserve_index_space 512 480P_600K_71149981_vthumb.webm 

Hier ist die Datei 480P_600K_71149981.mp4, auf der ich dies teste .

Und hier ist das Ergebnis, 480P_600K_71149981_vthumb.webm und der Textdump davon, der mit webm_parser_demo.exelibwebm erstellt wurde (etwas modifiziert, um hex anstelle von dezimal anzuzeigen). Die interessantesten Teile des Textdumps sind Suchen nach "Timecode:" und "Cluster".

 Cluster header: [309, 311) body: [311, 3487) Timecode: 0 SimpleBlock header: [31a, 31c) body: [31c, 323) track number: 2 frames: 1 timecode: 0 lacing: 0 (none) flags: visible, key frame frame byte range: [320, 323) SimpleBlock header: [323, 325) body: [325, 395) track number: 1 frames: 1 timecode: 7 lacing: 0 (none) flags: visible, key frame frame byte range: [329, 395) SimpleBlock header: [395, 397) body: [397, 39e) track number: 2 frames: 1 timecode: 15 lacing: 0 (none) flags: visible, key frame frame byte range: [39b, 39e) SimpleBlock header: [39e, 3a0) body: [3a0, 3bb) track number: 1 frames: 1 timecode: 28 lacing: 0 (none) flags: visible frame byte range: [3a4, 3bb) SimpleBlock header: [3bb, 3bd) body: [3bd, 3c4) track number: 2 frames: 1 timecode: 29 lacing: 0 (none) flags: visible, key frame frame byte range: [3c1, 3c4) 

Quell- und Zielvideo haben unterschiedliche fps, dies ist wahrscheinlich wichtig. Es gibt setpts=PTS-STARTPTSFilter, die den Startzeitpunkt von Presentation TimeStamp jedoch nicht beeinflussen.

Dies ist wichtig für mich, um sicherzustellen, dass das -force_key_framesKeyframe zum richtigen Zeitpunkt erstellt wird. Später verwende ich Timecodes, um nur einen Cue in der Datei zu hinterlassen. Ich versuche nur, es zu polieren, Videoformate zu lernen, während ich eine Chance habe. Ich werde später einen Videoplayer erstellen, um sicherzustellen, dass diese Dateien so einfach zu lesen und wiederzugeben sind wie möglich.

Wenn nur Video oder nur Audio vorhanden ist, beginnen die Timecodes ordnungsgemäß bei 0. Ich habe es mit diesem Befehl getestet:

ffmpeg -i 480P_600K_71149981.mp4 -t 3 -an -reserve_index_space 512 out.webm 

Ich frage mich auch, ob es möglich ist, Videoframes vor Audioframes zu verschieben, es scheint eine natürlichere Art zu sein, sie zu speichern, obwohl ich mir über nichts sicher bin. Es wird sich wahrscheinlich von selbst lösen, wenn das Zeitstempelproblem gelöst ist.

Wenn die Lösung etwas in ffmpeg ändern und neu kompilieren muss, bin ich damit einverstanden. Sie müssen nur herausfinden, was zuerst geändert werden muss.

Ich frage mich jedoch, ob ich eigentlich Audio vor dem Video behalten und verwenden sollte -audio_preload. Um Opus-Audio zu suchen, muss ich SeekPreRoll-Millisekunden trotzdem wiedergeben (in meinem Fall 80 ms). Nicht so, dass mir das wichtig ist. In diesem Fall möchte ich niemals in einem 12-Sekunden-Video suchen. Ich muss nur den Keyframe aus dem zweiten Teil eines Videos für das Miniaturbild nehmen. Ja nein -audio_preloadhier Außerdem gibt es hier einige verwirrende Informationen über das Muxen von Opus in matroska, die in diesem Fall wahrscheinlich nutzlos sind: https://wiki.xiph.org/MatroskaOpus .

Warten Sie, ich glaube, ich habe herausgefunden, warum das Video um 7 Millisekunden verzögert ist. Denn in Opus müssen Sie CodecDelay (hier 6,5 ms) des Audiomaterials abspielen und es einfach verwerfen, bevor irgendein Ton gehört werden kann, um den Decoder nur zu initialisieren. Hm, jetzt frage ich mich, ob ich diesen verworfenen Ton auf einen negativen Zeitstempel setzen kann. https://www.matroska.org/technical/specs/index.html#simpleblock_structure der timecode hier ist ein signiertes int16, also kann ich das wahrscheinlich. Aber wie sagt man das ffmpeg ...


Edit1: Hier ist die Ausgabe von ffprobe:

ffprobe 480P_600K_71149981_vthumb.webm -show_packets -select_streams v -read_intervals %+#5 -v 0 

-

[PACKET] codec_type=video stream_index=0 pts=7 pts_time=0.007000 dts=7 dts_time=0.007000 duration=33 duration_time=0.033000 convergence_duration=N/A convergence_duration_time=N/A size=108 pos=897 flags=K_ [/PACKET] [PACKET] codec_type=video stream_index=0 pts=40 pts_time=0.040000 dts=40 dts_time=0.040000 duration=33 duration_time=0.033000 convergence_duration=N/A convergence_duration_time=N/A size=23 pos=1020 flags=__ [/PACKET] [PACKET] codec_type=video stream_index=0 pts=74 pts_time=0.074000 dts=74 dts_time=0.074000 duration=33 duration_time=0.033000 convergence_duration=N/A convergence_duration_time=N/A size=23 pos=1067 flags=__ [/PACKET] [PACKET] codec_type=video stream_index=0 pts=107 pts_time=0.107000 dts=107 dts_time=0.107000 duration=33 duration_time=0.033000 convergence_duration=N/A convergence_duration_time=N/A size=23 pos=1114 flags=__ [/PACKET] [PACKET] codec_type=video stream_index=0 pts=140 pts_time=0.140000 dts=140 dts_time=0.140000 duration=33 duration_time=0.033000 convergence_duration=N/A convergence_duration_time=N/A size=23 pos=1152 flags=__ [/PACKET] 

-

ffprobe 480P_600K_71149981_vthumb.webm -show_packets -select_streams a -read_intervals %+#5 -v 0 

-

[PACKET] codec_type=audio stream_index=1 pts=-7 pts_time=-0.007000 dts=-7 dts_time=-0.007000 duration=20 duration_time=0.020000 convergence_duration=N/A convergence_duration_time=N/A size=3 pos=888 flags=K_ [/PACKET] [PACKET] codec_type=audio stream_index=1 pts=14 pts_time=0.014000 dts=14 dts_time=0.014000 duration=20 duration_time=0.020000 convergence_duration=N/A convergence_duration_time=N/A size=3 pos=1011 flags=K_ [/PACKET] [PACKET] codec_type=audio stream_index=1 pts=34 pts_time=0.034000 dts=34 dts_time=0.034000 duration=20 duration_time=0.020000 convergence_duration=N/A convergence_duration_time=N/A size=3 pos=1049 flags=K_ [/PACKET] [PACKET] codec_type=audio stream_index=1 pts=54 pts_time=0.054000 dts=54 dts_time=0.054000 duration=20 duration_time=0.020000 convergence_duration=N/A convergence_duration_time=N/A size=3 pos=1058 flags=K_ [/PACKET] [PACKET] codec_type=audio stream_index=1 pts=74 pts_time=0.074000 dts=74 dts_time=0.074000 duration=20 duration_time=0.020000 convergence_duration=N/A convergence_duration_time=N/A size=3 pos=1096 flags=K_ [/PACKET] 

Wirklich seltsam, wie Video den ersten Zeitstempel 7 und Audio den ersten Zeitstempel -7 hat.

In der Matroska (geprüft mit webm_parser_demo.exe) hat Video Zeitstempel 7 und Audio hat Zeitstempel 0.

Mein Ziel ist es, den ersten Video-Zeitstempel auf 0 und den ersten Audio-Zeitstempel auf -7 (alle CodecDelay-Daten) zu setzen.


Edit2: Studierte ein paar Webm mit vorbisAudio, sie beginnen auch nicht beide bei 0. In ihnen beginnt Audio bei 0 und Video bei 3. Weiß nicht, was damit los ist, ist es auch CodecDelay?

2
ffmpeg setzt bereits das erste Audiopaket auf -ve TS. Überprüfen Sie die ersten paar Pakete jedes Streams mit ffprobe. Gyan vor 6 Jahren 0
@ Mulvya Was ist "-ve TS" und wie lautet der Befehl zum Überprüfen der ersten 5 Pakete? siods333333 vor 6 Jahren 0
-ve == negativer TS = Zeitstempel. Befehl = `ffprobe file.mp4 -show_packets -select_streams v -read_intervals% + # 5 -v 0` für Video. Ändern Sie "v" in "a" für Audio. Gyan vor 6 Jahren 0
@ Mulvya, hinzugefügt ffprobe Ausgabe. Entschuldigung für die Verspätung. siods333333 vor 6 Jahren 0
Verwenden Sie mkvmerge.exe, um Dateien mit einem Klick zu remuxen user902300 vor 5 Jahren 0

0 Antworten auf die Frage