#audio #video #ffmpeg
#Аудио #Видео #ffmpeg
Вопрос:
У меня есть видео, video.mp4, продолжительностью 30 секунд, и у меня есть аудио, длина которого может меняться, audio.mp3.
Моя последняя идея состоит в том, чтобы иметь выходное видео с циклом video.mp4 для общей длины audio.mp3 и наложение формы сигнала audio.mp3. То, что я сделал, это в скрипте bash:
# calculate length of the audio and of the video
tot=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 audio.mp3)
vid=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 video.mp4)
# how many base video we need to loop into the waveform video?
repeattime=`echo "scale=0; ($tot $vid-1)/$vid" | bc`
# ffmpeg final command
ffmpeg -stream_loop $repeattime -i video.mp4 -i audio.mp3 -filter_complex "[1:a]showwaves=s=1280x100:colors=Red:mode=cline:rate=25:scale=sqrt[outputwave]; [0:v][outputwave] overlay=0:main_h-overlay_h [out]" -map '[out]' -map '1:a' -c:a copy -y output.mp4
Есть ли лучший способ сделать это с помощью одной команды ffmpeg? Я знаю, что в ffmpeg существует фильтр циклов, но он зацикливает кадры, и я не знаю количество кадров видео.mp4. Кроме того, использование $repeattime может привести к увеличению количества циклов дольше, чем необходимо (поскольку математические вычисления выполняются округлением)
Ответ №1:
-shortest
помогает вам:
#!/bin/bash
ffmpeg -hide_banner -stream_loop -1 -i "input 1.mp4" -i "input 1.mp3" -filter_complex "
[1:a]showwaves=s=1280x100:colors=Red:mode=cline:rate=25:scale=sqrt[outputwave];
[0:v][outputwave] overlay=0:main_h-overlay_h [v]
" -map [v] -map 1:a -c:a copy -shortest -y output.mp4
Ответ №2:
Вы можете использовать самый короткий вариант в overlay.
ffmpeg -stream_loop -1 -i video.mp4 -i audio.mp3 -filter_complex "[1:a]showwaves=s=1280x100:colors=Red:mode=cline:rate=25:scale=sqrt[outputwave]; [0:v][outputwave] overlay=0:main_h-overlay_h:shortest=1 [out]" -map '[out]' -map '1:a' -c:a copy -y output.mp4