FFmpeg视频剪辑合并:音频交叉淡入淡出功能实现求助
问题:实现part2.mp4与pip.mp4之间的音频交叉淡入淡出效果
本文已更新
提前感谢各位提供的帮助!
我正在处理4个规格一致的立体声音频视频素材:
- intro
- mainvideo
- midroll_video(广告)
- endboard
我需要在代码生成的part2.mp4和pip.mp4之间添加仅音频的交叉淡入淡出效果。已按照@Баяр Гончикжапов的指导修改代码,但仍无法正常工作,以下是我使用的代码,恳请协助排查问题。
感谢各位的帮助!
# Input parameters mainvideo=mezzfile.mp4 endboard=endboard.mp4 intro=sting.mp4 midroll_video=midroll.mp4 tailtime=20 fadelength=0.2 midroll_edit_value=00:11:31.600 # Time calculations to define cut point duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $mainvideo) endboard_cut_point=$(echo "scale=2;$duration-$tailtime" | bc) duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $mainvideo) midroll_cut_point=$(echo "scale=2;$duration-$midroll_edit_value" | bc) # Safety check tbn_main=$(ffprobe -v error -select_streams v -show_entries stream=time_base -of default=noprint_wrappers=1:nokey=1 $mainvideo) tbn_main=${tbn_main#*/} tbn_intro=$(ffprobe -v error -select_streams v -show_entries stream=time_base -of default=noprint_wrappers=1:nokey=1 $intro) tbn_intro=${tbn_intro#*/} tbn_end=$(ffprobe -v error -select_streams v -show_entries stream=time_base -of default=noprint_wrappers=1:nokey=1 $endboard) tbn_end=${tbn_end#*/} if [[ $(( ($tbn_intro+$tbn_main+$tbn_end)/3 )) -ne $tbn_main ]]; then echo "WARNING: source video files have the different timebase." echo "The use of the concat demuxer will produce incorrect output." echo "Re-encoding is highly recommended." read -s -k $'?Press any key to exit.\n' exit 1 fi # Trim the main part of mainvideo ffmpeg -hide_banner -y -i $mainvideo -to $midroll_edit_value -c copy part1.mp4 ffmpeg -hide_banner -y -i $mainvideo -ss $midroll_edit_value -to $endboard_cut_point -c copy part2.mp4 ffmpeg -hide_banner -y -i $mainvideo -ss $midroll_edit_value -to $duration -c copy part2av.mp4 # Trim the tail of mainvideo and overlay it onto endboard ffmpeg -hide_banner -y \ -i $mainvideo \ -i $endboard \ -filter_complex \ "[0:v]select='gt(t,$duration-$tailtime)',scale=w=iw/2.03:h=ih/2.03,setpts=PTS-STARTPTS[v_tail]; \ [0:a]aselect='gt(t,$duration-$tailtime)',asetpts=PTS-STARTPTS[a_out]; \ [1:v][v_tail]overlay=format=auto[v_out]" \ -map "[v_out]" \ -map "[a_out]" \ -video_track_timescale $tbn_main \ pip.mp4 ffmpeg -hide_banner -y -i "part2.mp4" -i "part2av.mp4" -i "pip.mp4" \ -filter_complex \ -map "[0:v];" -map "[1:a];" -map "[2:v]" -c copy "part2pip.mp4" \ # Pass all parts through the concat demuxer [ -f filelist.txt ] && rm filelist.txt for f in $intro part1.mp4 $midroll_video part2pip.mp4; do echo "file '$PWD/$f'" >> filelist.txt; done ffmpeg -hide_banner -y -f concat -safe 0 -i filelist.txt -c copy TEST_FILE.mp4 # Sweep the table rm pip.mp4 part1.mp4 part2.mp4 filelist.txt
问题排查与修正方案
1. 核心语法错误
你生成part2pip.mp4的ffmpeg命令存在致命语法问题:
-filter_complex参数后直接跟-map属于非法写法,-map是全局选项,不能嵌套在滤镜链中- 完全没有实现音频淡入淡出的滤镜逻辑
2. 音频交叉淡入淡出的实现逻辑
要实现part2.mp4音频淡出、pip.mp4音频淡入的交叉效果,需要:
- 对
part2.mp4的音频应用afade=t=out:d=$fadelength实现淡出 - 对
pip.mp4的音频应用afade=t=in:d=$fadelength实现淡入 - 用
amix滤镜混合两个处理后的音频,同时用concat拼接两段视频
3. 修正后的关键代码片段
替换原脚本中生成part2pip.mp4的命令:
# 实现音频交叉淡入淡出并合并视频 ffmpeg -hide_banner -y \ -i "part2.mp4" \ -i "pip.mp4" \ -filter_complex \ "[0:a]afade=t=out:d=$fadelength[a_out]; \ [1:a]afade=t=in:d=$fadelength[a_in]; \ [a_out][a_in]amix=inputs=2:duration=first[a_mix]; \ [0:v][1:v]concat=n=2:v=1:a=0[v_concat]" \ -map "[v_concat]" \ -map "[a_mix]" \ -c:v libx264 -c:a aac "part2pip.mp4"
4. 其他冗余优化
- 删除未使用的
midroll_cut_point变量计算逻辑 - 移除冗余的
part2av.mp4生成步骤,直接使用pip.mp4的原音频即可
完整修正后的脚本
# Input parameters mainvideo=mezzfile.mp4 endboard=endboard.mp4 intro=sting.mp4 midroll_video=midroll.mp4 tailtime=20 fadelength=0.2 midroll_edit_value=00:11:31.600 # Time calculations to define cut point duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $mainvideo) endboard_cut_point=$(echo "scale=2;$duration-$tailtime" | bc) # Safety check tbn_main=$(ffprobe -v error -select_streams v -show_entries stream=time_base -of default=noprint_wrappers=1:nokey=1 $mainvideo) tbn_main=${tbn_main#*/} tbn_intro=$(ffprobe -v error -select_streams v -show_entries stream=time_base -of default=noprint_wrappers=1:nokey=1 $intro) tbn_intro=${tbn_intro#*/} tbn_end=$(ffprobe -v error -select_streams v -show_entries stream=time_base -of default=noprint_wrappers=1:nokey=1 $endboard) tbn_end=${tbn_end#*/} if [[ $(( ($tbn_intro+$tbn_main+$tbn_end)/3 )) -ne $tbn_main ]]; then echo "WARNING: source video files have the different timebase." echo "The use of the concat demuxer will produce incorrect output." echo "Re-encoding is highly recommended." read -s -k $'?Press any key to exit.\n' exit 1 fi # Trim the main part of mainvideo ffmpeg -hide_banner -y -i $mainvideo -to $midroll_edit_value -c copy part1.mp4 ffmpeg -hide_banner -y -i $mainvideo -ss $midroll_edit_value -to $endboard_cut_point -c copy part2.mp4 # Trim the tail of mainvideo and overlay it onto endboard ffmpeg -hide_banner -y \ -i $mainvideo \ -i $endboard \ -filter_complex \ "[0:v]select='gt(t,$duration-$tailtime)',scale=w=iw/2.03:h=ih/2.03,setpts=PTS-STARTPTS[v_tail]; \ [0:a]aselect='gt(t,$duration-$tailtime)',asetpts=PTS-STARTPTS[a_out]; \ [1:v][v_tail]overlay=format=auto[v_out]" \ -map "[v_out]" \ -map "[a_out]" \ -video_track_timescale $tbn_main \ pip.mp4 # 实现音频交叉淡入淡出并合并视频 ffmpeg -hide_banner -y \ -i "part2.mp4" \ -i "pip.mp4" \ -filter_complex \ "[0:a]afade=t=out:d=$fadelength[a_out]; \ [1:a]afade=t=in:d=$fadelength[a_in]; \ [a_out][a_in]amix=inputs=2:duration=first[a_mix]; \ [0:v][1:v]concat=n=2:v=1:a=0[v_concat]" \ -map "[v_concat]" \ -map "[a_mix]" \ -c:v libx264 -c:a aac "part2pip.mp4" # Pass all parts through the concat demuxer [ -f filelist.txt ] && rm filelist.txt for f in $intro part1.mp4 $midroll_video part2pip.mp4; do echo "file '$PWD/$f'" >> filelist.txt; done ffmpeg -hide_banner -y -f concat -safe 0 -i filelist.txt -c copy TEST_FILE.mp4 # Sweep the table rm pip.mp4 part1.mp4 part2.mp4 filelist.txt
内容的提问来源于stack exchange,提问作者3EK
相关产品推荐
相关产品推荐

