首页 / FFmpeg 入门教程 / 截取片段与精确定位

FFmpeg 入门教程

截取片段与精确定位

本教程共 32 篇 · 第 11 篇 · 更新于 2026-08-09 · 约 6 分钟阅读

FFmpeg截取-ss-t-toseek精确定位关键帧

本节目标:能用 -ss-t-to 切出任意时间段,并理解「秒切但不精确」和「精确但慢」两种方式的取舍。

剪视频最常见的需求就是「把第 2 分钟到第 5 分钟切出来」。这件事做起来简单,但参数位置有讲究,搞不好会出现「写了 5 分钟,结果切到 7 分钟」的怪事。这一章把定位机制讲清楚。

三个核心参数

  • -ss 位置:起始时间。
  • -t 时长:截取多长时间。
  • -to 位置:结束时间。

时间可以写成两种格式:

  • 时分秒:00:01:3001:30(1 分 30 秒)。
  • 秒数:9090.500:01:30.500
Note

-t-to 同时出现时,-t 优先。

参数放在 -i 前还是后

这是最容易踩坑的地方。

输入定位(-ss 放在 -i 之前)

ffmpeg -ss 00:02:00 -i input.mp4 -t 180 -c copy cut.mp4

-ss 写在 -i 前面叫输入定位。FFmpeg 会直接跳到起始时间最近的关键帧,然后从那里开始读。

  • 优点:非常快,因为不用解码前面的内容。
  • 缺点
    • -c copy 时,切点只能落在关键帧上,可能比你指定的时间早几秒钟。
    • 时间戳会被重置:输出文件里起始点变成 0 秒。

从 FFmpeg 2.1 起,如果配合重编码(不是 -c copy),输入定位同样可以做到帧精确:FFmpeg 会跳到关键帧,解码中间多余的帧并丢掉。

输出定位(-ss 放在 -i 之后)

ffmpeg -i input.mp4 -ss 00:02:00 -t 180 cut.mp4

-ss 写在 -i 后面叫输出定位。FFmpeg 会从头开始解码,一直解到目标时间,把前面的帧丢掉。

  • 优点:帧精确,滤镜(比如烧字幕)能正确处理时间戳。
  • 缺点:慢,起始时间越远等得越久。

简单记忆

方式速度精度(流复制)精度(重编码)
-ss-i关键帧级(可能差几秒)帧精确
-ss-i帧精确帧精确

三种典型方案

方案 A:秒切,能接受关键帧误差

ffmpeg -ss 00:02:00 -to 00:05:00 -i input.mp4 -c copy cut.mp4

或者用 -t

ffmpeg -ss 00:02:00 -t 180 -i input.mp4 -c copy cut.mp4

速度极快,但切点会对齐到关键帧。适合快速剪片、不在乎前后多几秒。

方案 B:快速且帧精确(重编码)

ffmpeg -ss 00:02:00 -to 00:05:00 -i input.mp4 -c:v libx264 -c:a aac cut.mp4

-ss 在前面,不写 -c copy。FFmpeg 会跳到附近关键帧,解码多余部分并丢掉,切点精确。速度取决于编码速度。

方案 C:输出定位(最精确但最慢)

ffmpeg -i input.mp4 -ss 00:02:00 -to 00:05:00 -c:v libx264 -c:a aac cut.mp4

适合需要加滤镜、时间戳敏感的场景。但开头有多长就要解多久,剪 1 小时的片子要等半天。一般用方案 B 就够了。

-to 的时间戳陷阱

-ss-i 前面时,输入的时间戳会被重置为 0。这意味着:

ffmpeg -ss 00:02:00 -i input.mp4 -to 00:05:00 -c copy cut.mp4

你可能以为是切 2 分到 5 分(3 分钟),但实际上 -to 00:05:00 被当作相对于新起点的时长,切出来的是 2 分到 7 分(5 分钟)。

正确写法有两种:

把 -t/-to 和 -ss 一起放在 -i 前面(推荐):

ffmpeg -ss 00:02:00 -to 00:05:00 -i input.mp4 -c copy cut.mp4

这样 -to 是相对于原始时间轴的,结果是 2 分到 5 分。

或者用 -t 指定时长,不容易搞混:

ffmpeg -ss 00:02:00 -t 180 -i input.mp4 -c copy cut.mp4

切 3 分钟,不会算错。

从结尾倒着定位

-sseof-ss,但从文件结尾往前算。取最后 30 秒:

ffmpeg -sseof -30 -i input.mp4 -c copy ending.mp4

值必须是负数,表示距离结尾多少秒。

拼接友好的时间戳

-c copy 切出来的片段如果要用 concat 拼回去(见 §14),建议加 -avoid_negative_ts make_zero

ffmpeg -ss 00:02:00 -t 180 -i input.mp4 -c copy -avoid_negative_ts make_zero cut.mp4

这会把片段的时间戳平移到从 0 开始,避免拼接时出现音画不同步。

按文件大小或时间切分

想把一个长视频平均切成几段,可以配合 -fs(限制输出大小)或在脚本里循环用 -ss/-t。更简单的是 segment 封装器:

ffmpeg -i input.mp4 -c copy -f segment -segment_time 600 -reset_timestamps 1 part_%03d.mp4
  • -f segment:用 segment 格式输出。
  • -segment_time 600:每段 600 秒(10 分钟)。
  • -reset_timestamps 1:每段时间戳从 0 开始。
  • 输出文件 part_000.mp4part_001.mp4……

同样,流复制模式下切点会落在关键帧附近,时长不会完全精确。

边播放边预览截取

用 ffplay 先看一眼切得对不对,不生成文件:

ffplay -ss 00:02:00 -t 10 input.mp4

从第 2 分钟开始播 10 秒。确认位置对了再上 ffmpeg。

常用命令速查

# 从 1:30 开始切 30 秒,流复制秒切
ffmpeg -ss 00:01:30 -t 30 -i input.mp4 -c copy cut.mp4

# 从 1:30 切到 2:00,输入定位 + 重编码(帧精确)
ffmpeg -ss 00:01:30 -to 00:02:00 -i input.mp4 -c:v libx264 -c:a aac cut.mp4

# 从第 10 秒切到第 20 秒,输出定位
ffmpeg -i input.mp4 -ss 10 -to 20 -c:v libx264 cut.mp4

# 最后 10 秒
ffmpeg -sseof -10 -i input.mp4 -c copy ending.mp4

# 每 10 分钟切一段
ffmpeg -i input.mp4 -c copy -f segment -segment_time 600 -reset_timestamps 1 part_%03d.mp4

小结

  • -ss 定起点,-t 定时长,-to 定终点;-t-to 同时给时 -t 优先。
  • -ss-i 前是输入定位(快),在后面是输出定位(慢)。
  • 配合 -c copy 只能关键帧级精确;要帧精确就重编码。
  • 推荐把 -ss-t/-to 一起放在 -i 前面,避免时间戳重置的坑。
  • 切出来要拼接就加 -avoid_negative_ts make_zero

下一章讲截图:从视频里抓一帧或多帧画面,以及生成缩略图拼图。