Здравствуйте. Готовлю небольшой фильм, когда сцен стало слишком много и ждать сборки всего за раз стало долго, решил сделать инкрементальную сборку сцен на основе Makefile’а. Во всех исходниках сцен png фреймы, фпс везде == 30
define scenes_nl
scene_90
scene_91
scene_92
...
endef
c_options := -movflags +faststart
v_options := -c:v libx264 -crf 18 -preset veryfast -pix_fmt yuv420p
a_options := -c:a aac -b:a 128k
define NL
endef
scenes := $(subst ${NL}, ,${scenes_nl})
parts = $(addsuffix .mp4, $(addprefix parts/,${scenes}))
output.mp4 : ${parts} global_audio/audio.m4a
if [[ -e list_tmp.txt ]]; then rm list_tmp.txt; fi
for f in ${parts}; do echo "file '$${f}'" >> list_tmp.txt; done
ffmpeg -f concat -i list_tmp.txt -c copy ${c_options} output_inter.mp4
ffmpeg -y -i output_inter.mp4 -i global_audio/audio.m4a -filter_complex "[0:1][1:0]amix[ma]"\
-map 0:0 -map "[ma]" -c:v copy -shortest ${a_options} ${c_options} $@
rm output_inter.mp4
parts/%.mp4 : %
if ! [[ -e $?/audio.m4a ]]; then cp -i empty.m4a $?/audio.m4a; fi
ffmpeg -y -framerate 30 -i $?/%04d.png -i $?/audio.m4a -map 0:0 -map 1:0 -shortest ${c_options} ${v_options} ${a_options} $@
clean:
#-for s in ${scenes}; do rm $${s}/audio.m4a; done
-rm parts/*
-rm list_tmp.txt
touch:
-for s in ${scenes}; do touch $${s}; done
Суть элементарная - сперва клепаю mp4 из каждой сцены (ffmpeg -y -framerate 30 -i $?/%04d.png -i $?/audio.m4a -map 0:0 -map 1:0 ${ffmpeg_options} $@), затем сливаю всё в один контейнер без перекодировки (ffmpeg -y -f concat -i list_tmp.txt -c copy $@).
Но появилась проблема - в выхлопе на втором шаге появились сообщения «Non-monotonic DTS; previous: 3803896, current: 3803875; changing to 3803897. This may result in incorrect timestamps in the output file» + если фпс в начале был 30, то у выходного файла он в районе 29.64. Что происходит? Как получить желаемое? Может на первом шаге mp4 неподходящий контейнер?
Заметил, что если аудио поток не шить в видики на первом шаге, то фпс у видика на вотором шаге == ожидаемым 30, но сообщения о DTS это не устраняет