从视频提取指定区域画面并合成新视频的FFmpeg技术问询
优化FFmpeg批量裁剪视频区域并合成的工作流
嘿,我看你现在是用两步FFmpeg操作来提取视频里的多个指定裁剪区域,先导出图片再合成视频对吧?其实咱们可以把流程优化得更高效,要么一步完成(省去中间生成图片的步骤),要么把现有命令整理得更易读,下面给你具体方案:
一、直接一步完成裁剪+合成(推荐)
这种方式不用生成中间图片文件,既节省磁盘空间,又能减少IO开销,速度更快。根据你的合成需求,分两种场景:
1. 按顺序播放多个裁剪片段
如果想先播放第一个裁剪区域的内容,再依次播放后面的,用concat滤镜:
ffmpeg -y -i INPUT -filter_complex " [0:v]crop=704:396:500:500,scale=1920:-1[v0]; [0:v]crop=708:398:502:502,scale=1920:-1[v1]; [0:v]crop=711:399:505:505,scale=1920:-1[v2]; [0:v]crop=715:402:508:508,scale=1920:-1[v3]; [v0][v1][v2][v3]concat=n=4:v=1:a=0[vout] " -map "[vout]" output.mp4
- 小提示:
concat=n=4表示要拼接4个视频流,v=1代表只处理视频轨道,a=0表示忽略音频;如果需要保留音频,你得给每个裁剪流也处理音频,再同步拼接。
2. 四格分屏同时展示所有区域
如果想把4个裁剪区域的画面同时分屏显示,用xstack滤镜(先把每个画面缩放到合适尺寸,避免拼接后分辨率异常):
ffmpeg -y -i INPUT -filter_complex " [0:v]crop=704:396:500:500,scale=960:540[v0]; [0:v]crop=708:398:502:502,scale=960:540[v1]; [0:v]crop=711:399:505:505,scale=960:540[v2]; [0:v]crop=715:402:508:508,scale=960:540[v3]; [v0][v1][v2][v3]xstack=layout=2x2[vout] " -map "[vout]" output.mp4
- 解释:先把每个裁剪后的画面缩放到960x540,这样2x2拼接后刚好是1920x1080的标准分辨率,适配大多数播放场景。
二、如果必须保留“先导出图片再合成”的流程
要是你因为某些特殊需求必须先导出单帧图片,那可以把原始命令整理得更清晰,加上注释方便后续维护:
ffmpeg -y -i INPUT -filter_complex " # 裁剪区域1:尺寸704×396,起始坐标(500,500),缩放至1920宽(高度按比例自动调整) [0:v]crop=704:396:500:500,scale=1920:-1[mvid0]; # 裁剪区域2:尺寸708×398,起始坐标(502,502) [0:v]crop=708:398:502:502,scale=1920:-1[mvid1]; # 裁剪区域3:尺寸711×399,起始坐标(505,505) [0:v]crop=711:399:505:505,scale=1920:-1[mvid2]; # 裁剪区域4:尺寸715×402,起始坐标(508,508) [0:v]crop=715:402:508:508,scale=1920:-1[mvid3] " \ -map "[mvid0]" "000000.png" \ -map "[mvid1]" "000001.png" \ -map "[mvid2]" "000002.png" \ -map "[mvid3]" "000003.png"
然后用这条命令把导出的图片合成视频(帧率可以根据你的需求调整,这里用24帧示例):
ffmpeg -y -framerate 24 -i "00000%d.png" -c:v libx264 -pix_fmt yuv420p output.mp4
内容的提问来源于stack exchange,提问作者Nik




