FFmpeg 从入门到深入(三):剪切与合并的正确姿势
> 系列第三篇。剪切和合并看似最简单,其实坑最多:剪出来的视频开头黑屏、音画不同步、合并后时间轴错乱……这篇把 `-ss/-to`、concat 解复用器和 concat 滤镜三种做法一次讲清,按场景直接用。
## 剪切:-ss 和 -to 的位置很关键
最直观的写法是把 `-ss` 放在 `-i` 前面(输入侧定位):
```bash
ffmpeg -ss 00:01:30 -i input.mp4 -to 00:00:30 -c copy output.mp4
```
这条命令从第 1 分 30 秒开始,截取 30 秒,`-c copy` 不重编码,几秒钟出结果。使用时有三个必须知道的点:
- **`-ss` 在 `-i` 前是"快速定位"**,直接跳到关键帧附近;在 `-i` 后是"精确解码定位",慢但帧级精确。要求切点绝对准确(比如卡台词)就把 `-ss` 放到 `-i` 后面,并去掉 `-c copy` 改为重编码。
- **`-to` 在输入侧是相对 `-ss` 的时长**(现代 FFmpeg 的语义),不是绝对时间点。想用绝对时间点就用 `-t` 表示持续时长,含义更不容易混淆:`-ss 90 -t 30`。
- **`-c copy` 剪切只能切在关键帧上**,切点会向前吸附到最近的关键帧,结果可能比预期多出零点几秒;开头偶尔黑屏也是这个原因。要干净就重编码。
只剪一段保留原画质、又嫌关键帧吸附麻烦,折中方案:只重编码视频,音频直接拷贝——`-c:v libx264 -crf 18 -c:a copy`,速度快还能保证切点精确。
## 合并:先看两段素材"长"得一样不一样
合并失败九成是因为素材参数不一致:分辨率、帧率、编码、音轨采样率任意一个不同,都可能报错或产出错乱文件。动手前先用 `ffprobe` 对比两段素材的编码、分辨率、帧率:
```bash
ffprobe -v error -show_entries stream=codec_name,width,height,r_frame_rate -of json a.mp4 b.mp4
```
### 方法一:concat 解复用器(快,不重编码)
把要合并的文件写进一个列表:
```bash
printf "file 'a.mp4'\nfile 'b.mp4'\n" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy merged.mp4
```
`-safe 0` 允许列表里出现绝对路径。要求所有文件编码参数完全一致,否则要么直接报错,要么音画不同步。适合分段录制的同一台设备素材。
### 方法二:concat 滤镜(慢,但能吃掉不一致)
```bash
ffmpeg -i a.mp4 -i b.mp4 -filter_complex \
"[0:v]scale=1920:1080,setsar=1[v0];[1:v]scale=1920:1080,setsar=1[v1];[v0][v1]concat=n=2:v=1:a=0[v]" \
-map "[v]" -c:v libx264 -crf 23 out.mp4
```
先把两路视频统一缩放到同分辨率、清掉 SAR(像素宽高比)差异,再交给 `concat` 滤镜拼接。代价是视频全程重编码,慢;好处是分辨率不同的素材也能拼。
带音频的版本把音轨也接上:每个输入各自 `[0:a][1:a]` 做 `concat=n=2:v=1:a=1`,输出两路 `[v][a]` 再用 `-map` 分别指定。
## 常见坑速查
- 合并后**只有第一段有声音**:多半是音轨参数不一致,用 concat 滤镜并把音频也重编码成同一种(`-c:a aac -ar 48000 -ac 2`)。
- 剪切结果**开头多一段、结尾少一段**:`-c copy` 关键帧吸附,换精确模式。
- 合并结果**时间轴越来越慢/快**:两段帧率不同,先统一 `-r`。
- 列表文件里路径带空格:单引号包住,Windows 盘符路径写成 `file 'C:/videos/a.mp4'`。
## 小结
剪切三句话:要快用输入侧 `-ss` + `-c copy`,要准用输入侧解码定位或重编码,`-t` 比 `-to` 不容易混淆。合并两句话:参数一致走 concat 解复用器(秒级),不一致走 concat 滤镜(重编码)。下一篇讲音频处理:提取音轨、格式转换、音量归一化和简单降噪。
- 点赞
- 收藏
- 关注作者
评论(0)