使用FFmpeg合成WAV与PNG时输出视频不完整的问题
问题分析与解决
核心问题
- concat demuxer的
duration指令限制:duration仅对前一个文件生效,最后一张图的duration 7不会被FFmpeg识别,导致第6张图仅显示1帧(约0.04秒),视频实际时长仅为前5张的30秒。 -shortest参数截断音频:该参数强制输出时长与最短输入流一致,视频的30秒时长直接导致音频被同步截断。
解决方案
方案1:修正concat文件并调整命令
步骤1:修改concat列表文件
在最后添加一个空文件占位行(无需实际文件,仅用于触发最后一个duration生效):
file '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide1.png' duration 6 file '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide2.png' duration 6 file '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide3.png' duration 6 file '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide4.png' duration 6 file '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide5.png' duration 6 file '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide6.png' duration 7 file '/dev/null' # 占位用,触发最后一个duration生效
步骤2:调整FFmpeg命令
移除-shortest参数以保留完整音频,同时移除-strict experimental(FFmpeg 5.x中AAC编码器已稳定):
'/opt/homebrew/Cellar/ffmpeg/5.1.2_6/bin/ffmpeg' -y -f concat -safe 0 -i '/private/var/folders/bb/m2b0ry595ys7bfs1r397lnf40000gp/T/Rtmp8gnKo7/ari_input_NQIg95oycVnb.txt' -i '/private/var/folders/bb/m2b0ry595ys7bfs1r397lnf40000gp/T/Rtmp8gnKo7/ari_audio_ngNm5vr2vFta.wav' -c:v libx264 -c:a aac -ac 2 -fps_mode auto -pix_fmt yuv420p -vf fps=5,"scale=trunc(iw/2)*2:trunc(ih/2)*2" -max_muxing_queue_size 9999 -threads 2 '/var/folders/bb/m2b0ry595ys7bfs1r397lnf40000gp/T//Rtmp8gnKo7/file46521ffd4ef8.mp4'
方案2:使用concat滤镜(无需中间文件,推荐)
直接通过滤镜链处理每张图片的时长并拼接,彻底避免concat demuxer的限制:
'/opt/homebrew/Cellar/ffmpeg/5.1.2_6/bin/ffmpeg' -y \ -loop 1 -i '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide1.png' \ -loop 1 -i '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide2.png' \ -loop 1 -i '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide3.png' \ -loop 1 -i '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide4.png' \ -loop 1 -i '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide5.png' \ -loop 1 -i '/Users/howardbaek/Documents/sandbox/loqui/png_files/slide6.png' \ -i '/private/var/folders/bb/m2b0ry595ys7bfs1r397lnf40000gp/T/Rtmp8gnKo7/ari_audio_ngNm5vr2vFta.wav' \ -filter_complex "\ [0:v]trim=duration=6,setpts=PTS-STARTPTS[v0];\ [1:v]trim=duration=6,setpts=PTS-STARTPTS[v1];\ [2:v]trim=duration=6,setpts=PTS-STARTPTS[v2];\ [3:v]trim=duration=6,setpts=PTS-STARTPTS[v3];\ [4:v]trim=duration=6,setpts=PTS-STARTPTS[v4];\ [5:v]trim=duration=7,setpts=PTS-STARTPTS[v5];\ [v0][v1][v2][v3][v4][v5]concat=n=6:v=1:a=0[v];\ [v]fps=5,scale=trunc(iw/2)*2:trunc(ih/2)*2[vout]" \ -map "[vout]" -map 6:a \ -c:v libx264 -c:a aac -ac 2 -pix_fmt yuv420p \ -max_muxing_queue_size 9999 -threads 2 '/var/folders/bb/m2b0ry595ys7bfs1r397lnf40000gp/T//Rtmp8gnKo7/file46521ffd4ef8.mp4'
该命令会循环播放每张图片并按指定时长截取,拼接后自动调整帧率和分辨率,同时完整保留音频流。
内容的提问来源于stack exchange,提问作者Howard Baik
相关产品推荐
相关产品推荐

