Я использую ffmpeg для объединения большого количества видеофайлов, используя filter_complex. Тем не менее, файл результатов имеет аудио несинхронизирован постепенно.
и я использую mediainfo --Inform='Video;%Duration%' filename.ext
и mediainfo --Inform='Audio;%Duration%' filename.ext
чтобы отобразить номер продолжительности в следующем процессе.
Вот как воспроизвести мою проблему, учитывая исходный файл:
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
размер слишком велик, но его видео и аудио дорожки имеют одинаковую длительность XXXXXXX мс, сообщает mediainfo
в целях тестирования я использую первые 5 секунд с двойным «-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
длительность результата (мс):
5004.000000 video of source_v5a5.mkv
5119.000000 audio of source_v5a5.mkv
разница составляет 119-4 = 115 мс, а mediainfo filename.ext
ничего не сообщает о задержке в данный момент, этот фрагмент хорошо воспроизводится, когда я его смотрю, возможно, с задержкой в 115 мс (в голове?) что не так заметно, как
[vvvvvvvvv………………v]
[-aaaaaaaaa………………a]
Теперь скопируйте этот файл 3 раза, делая вид, что у нас много разных фрагментов, затем отдельно кодируйте видео и аудио дорожки:
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"
да, я добавляю здесь acodec, но только выходной видеопоток. Теперь закодируйте аудио, передайте вывод ffmpeg в 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"
да, я добавляю vcodec сюда, но только вывод аудио потока.
длительность результата (мс):
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
разница превышает 200 мс, кажется, задержка включена во время concat? во время воспроизведения файла muxed, сначала все в порядке, но в последней части я чувствую задержку
при условии, что задержка в голове, она выглядит так:
[v111111v222222v333333v444444]
[-a111111-a222222-a333333-a444444]
как написано в документации: https://ffmpeg.org/ffmpeg-filters.html#concat
Фильтр concat будет использовать продолжительность самого длинного потока в каждом сегменте (кроме последнего) и, если необходимо, сокращать аудиопотоки с тишиной.
подозревая, что моего теста недостаточно, я проделал весь процесс снова с source_ v5a2.mkv и снова с source_ v5a10.mkv
продолжительность:
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 сделал так, как говорит документация (Silence дополнен, как если бы apad был применен / последний кадр заморожен), но результат остается примерно таким же: заметная задержка обнаружена в начале последнего сегмента
[v111111v222222v333333v444444]
[-a111___-a222___-a333___-a444]
а также
[v111___v222___v333___v444___]
[-a111111-a222222-a333333-a444444]
Приведенный выше тест содержит только 4 файла. При объединении 50+ файлов несинхронизация важна тем, что вы не можете ее игнорировать
Вопрос:
Учитывая кучу видеофайлов (50+, видео-аудио с одинаковым разрешением / кодеком / дорожкой # / и т.д., В основном одинаковой продолжительностью, некоторые нет) для согласования, как уменьшить / избежать задержки, чтобы сделать синхронизацию без заполнения видео на черном экране? лайк
[v111111v222222v333333v444444]
[-a111111a222222a333333a444444]
или даже лучше с задержкой обрезки (возможно, mkvmerge может справиться с этим после некоторого вычисления
[v111111v222222v333333v444444]
[a111111a222222a333333a444444]
было бы лучше, чтобы промежуточные файлы не создавались, трубопроводы в порядке
Обновить:
Возможно, я все понял неправильно. Возможно, это не задержка, а "растяжение / сжатие". Я запустил длинный тест, собрав 30 wmv-файлов, с помощью команды, подобной приведенной выше, я получил файл A с десинхронизацией более 1 с:
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=1
в фильтр перед asetpts и перекодирую в файл 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
Файл A также имеет проблему с синхронизацией, но файл B синхронизируется нормально! Таким образом, aresample=async=1
который применяется к аудио, на самом деле никак не влияет на аудио, а на видео! Я думаю, что это как-то связано с ПТС. После некоторого поиска в Google, я сделал следующее Опыт A:
- преобразовать 05:32:10.544000000 и 05:32:11.727000000 в 19930544 и 19931727
- используя mkvmerge, перетащите файл A, поместите 19931727/19930544 в поле « Растянуть по » видеодорожки, запустите Muxing
Синхронизация файла результатов в порядке (возможно, не заметная рассинхронизация), кажется, проблема синхронизации имеет какое-то отношение к PTS? Дальнейшие дополнительные исследования, скажем, правильно синхронизированный файл имеет большую продолжительность, в то время как десинхронный файл имеет более короткую продолжительность, я сделал следующее Exp B:
- используйте
mediainfo --Inform='General;%Duration%' filename.ext
чтобы получить длительность каждого файла - добавьте каждый номер продолжительности вверх
общая продолжительность составляет 05:32:10.438, почти столько же, сколько меньше
Новые вопросы:
- Мои первоначальные команды, они производили «Correct PTS, Longer Audio» или «Squeezed PTS, Correct Audio»?
- Если это «Правильный PTS, Longer Audio», как мне сделать звук правильным?
- Если это «Сжатый PTS, правильное аудио», используется ли
aresample=async=1
правильный способ исправить PTS при создании видео с нуля? - Если это «Squeezed PTS, Correct Audio», почему мой Exp B показывает, что общая продолжительность очень близка к более короткой (сжатой)?
- Если Exp B неверен, как я должен предсказать / вычислить правильную общую продолжительность перед процессом кодирования?
- Имея файл «Squeezed PTS, Correct Audio» без исходного файла, могу ли я исправить проблему синхронизации, растягивая / сжимая PTS, просто используя число «AudioDuration / VideoDuration»?
- Нужно ли
aresample=async=1
если используется не конкаталируемый файл, а просто кодирующий один файл, когда используется NO vf или af? Нужно ли использовать vf или af? Есть ли недостатки?
Это длинный текст выше, даже если вы не смогли ответить, спасибо, что дочитали до конца. :)