Как сделать так, чтобы видео и аудио таймкоды начинались с нуля?

1270
siods333333

Этот вопрос, вероятно, потребует знания формата matroska. Когда я смешиваю видео и аудио вместе, аудиопакеты начинаются с временного кода 0, а видео начинается с временного кода 7. Должно ли видео 30 кадров в секунду начинаться с временного кода 0 или с временного кода 33 (для времени 0,033 временные коды в миллисекундах)? Можно ли сделать так, чтобы аудио и видео начинались с таймкода 0?

Вам не нужно читать ниже, остальное просто дополнительная информация.


Я пытался добавить фильтры [v]setpts=N/(30*TB)[v];[a]asetpts=N/SR/TB[a]в качестве двух последних фильтров, но это ничего не изменило.

Вот полная команда, которую я использую. Это просто двухпроходное кодирование vp8 для видео и однопроходное кодирование opus для аудио. Он также нарезает видео на несколько частей длиной 3 секунды и объединяет их вместе.

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 

Вот файл 480P_600K_71149981.mp4, на котором я тестирую это.

И вот результат, 480P_600K_71149981_vthumb.webm и текстовый дамп этогоwebm_parser_demo.exe файла, созданный из libwebm (слегка измененный для отображения шестнадцатеричного вместо десятичного). Интересными частями текстового дампа являются поиск по «временному коду:» и «кластеру».

 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) 

Исходное и конечное видео имеют разные fps, это, вероятно, важно. Есть setpts=PTS-STARTPTSфильтры, но они, как ни странно, не влияют на начальную презентацию TimeStamp.

Это важно для меня, чтобы убедиться, что -force_key_framesключевой кадр создается в правильное время, и позже я буду использовать временные коды, чтобы оставить только 1 реплику в файле. Я просто пытаюсь отточить его, пытаюсь выучить видео форматы, пока у меня есть шанс. Я сделаю видеоплеер для тех позже, нужно, чтобы эти файлы были максимально просты для чтения и рендеринга.

Если есть только видео или только аудио, временные коды начинаются правильно с 0. Я проверил это с помощью этой команды:

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

Также мне интересно, можно ли сделать так, чтобы видеокадры шли раньше, чем аудио, это кажется более естественным способом их хранения, хотя я ни в чем не уверен. Он, вероятно, решит сам себя, как только проблема с временными метками будет решена.

Если решение требует изменения чего-либо в ffmpeg и перекомпиляции, я в порядке. Просто нужно сначала найти, что изменить.

Хотя мне интересно, должен ли я на самом деле сохранять звук перед видео и использовать -audio_preload. Потому что для поиска звука opus я все равно должен воспроизвести миллисекунды SeekPreRoll (80 мс в моем случае). Не то чтобы меня это беспокоило, в этом случае я не собираюсь искать внутри 12-секундного видео, мне нужно только быстро извлечь ключевой кадр из второй 3-й части видео для миниатюры. Да нет -audio_preloadздесь. Кроме того, здесь есть некоторая запутанная информация об опусном муксинге в matroska, вероятно, в этом случае бесполезная: https://wiki.xiph.org/MatroskaOpus .

Подождите, я думаю, я понял, почему видео задерживается на 7 миллисекунд. Потому что в opus вы должны проигрывать CodecDelay (здесь 6,5 мс) аудио и просто отбрасывать его, прежде чем можно будет услышать любой звук, просто для инициализации декодера. Хм, теперь мне интересно, смогу ли я установить этот отброшенный звук на отрицательную временную метку. https://www.matroska.org/technical/specs/index.html#simpleblock_structure здесь временной код представляет собой подписанный int16, так что, вероятно, я могу. Но как сказать это ffmpeg ...


Edit1: вот вывод 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] 

Действительно странно, как видео имеет первую метку времени 7, а аудио - первую метку времени -7.

В matroska (проверено с помощью webm_parser_demo.exe) видео имеет метку времени 7, а аудио имеет метку времени 0.

И моя цель - сделать первую отметку времени видео 0, а первую отметку времени аудио -7 (все данные CodecDelay).


Edit2: Изучил несколько webm со vorbisзвуком, они также не начинаются как с 0. В них аудио начинается с 0, а видео с 3. Не знаю, что с этим, это также CodecDelay?

2
ffmpeg уже устанавливает первый аудиопакет в -ve TS. Проверьте первую пару пакетов каждого потока, используя ffprobe. Gyan 6 лет назад 0
@Mulvya Что такое "-ve TS" и какова команда для проверки первых 5 пакетов? siods333333 6 лет назад 0
-ve == отрицательный TS = отметка времени. Команда = `ffprobe file.mp4 -show_packets -select_streams v -read_intervals% + # 5 -v 0` для видео. Замените `v` на` a` для аудио. Gyan 6 лет назад 0
@Mulvya, добавлен вывод ffprobe. Извините за задержку. siods333333 6 лет назад 0
используйте mkvmerge.exe для ремукса файлов одним кликом user902300 5 лет назад 0

0 ответов на вопрос

Похожие вопросы