8、流复制与重编码:codec copy与重新编码的区别、何时用copy、何时必须重编码

说实话,我刚入行那会儿,也被这两个概念搞晕过。明明都是转码,为什么有时候几秒钟就完事,有时候却要等半天?

后来我才明白——流复制(codec copy)和重编码,本质上干的是完全不同的活。一个是在搬砖,另一个是在重新造砖。

流复制:说白了就是“搬运工”

你想想看,一个MP4文件里,视频流是H.264编码的,音频流是AAC编码的。如果你只想换个封装格式,比如从MP4换成MKV,或者只想截取一段,那根本不需要重新压缩。

这时候就用 -c copy。它的意思是:“保持原样,直接搬过去”

核心特点:

  • 不解码、不编码,只做容器层面的操作
  • 速度极快,基本是磁盘I/O的极限
  • 画质、音质完全无损
  • 文件大小几乎不变
# 把MP4封装成MKV,视频和音频都保持原样
ffmpeg -i input.mp4 -c copy output.mkv

# 只截取前30秒,不重编码
ffmpeg -i input.mp4 -ss 0 -t 30 -c copy output.mp4

我在项目中遇到过这样一个场景:客户给了个TS格式的直播录制文件,播放器不支持。我直接用 -c copy 转成MP4,前后不到5秒,文件就搞定了。客户还以为我在糊弄他,哈哈。

重编码:这才是真正的“转码”

重编码就不一样了。它会把视频流完全解码成原始像素数据,然后再用新的编码器重新压缩。

说白了,就是先拆了房子,再用旧砖头盖新房。这个过程非常吃CPU或GPU,速度也慢得多。

# 把H.264视频重编码为H.265(HEVC)
ffmpeg -i input.mp4 -c:v libx265 -c:a copy output.mp4

# 改变分辨率,必须重编码
ffmpeg -i input.mp4 -vf scale=1280:720 -c:v libx264 output.mp4

注意:重编码是有损的。每次重编码都会引入画质损失。我见过有人把同一个视频反复转码了七八次,最后画面全是马赛克。嗯,千万别这么干。

什么时候用copy?什么时候必须重编码?

这个问题,我总结了一个简单的判断逻辑:

操作场景 能否用copy? 原因
更换封装格式(MP4→MKV) ✅ 可以 编码格式不变,只改容器
截取视频片段 ✅ 可以(注意关键帧对齐) 不改变编码数据
合并多个视频 ✅ 可以(参数需一致) 编码格式相同即可
改变分辨率/帧率 ❌ 必须重编码 需要重新采样像素
改变编码格式(H.264→H.265) ❌ 必须重编码 编码算法完全不同
添加水印/滤镜 ❌ 必须重编码 需要修改像素数据
调整码率/压缩比 ❌ 必须重编码 需要重新量化
修复损坏的视频 ⚠️ 视情况 部分损坏可用copy跳过

我的个人习惯:只要不涉及像素级别的修改,优先用copy。速度快、质量无损,何乐而不为?只有当你确实需要改变视频内容本身时,才考虑重编码。

一个容易踩的坑:关键帧对齐

-c copy 做截取时,有个细节很多人不知道——FFmpeg只能从关键帧开始截取

举个例子:你想从第10秒开始截,但第10秒刚好不是关键帧。那FFmpeg会自动往前找,找到最近的关键帧作为起点。结果你得到的片段,可能从第9.5秒就开始了。

我曾经因为这个被客户投诉过,说截出来的视频开头多了半秒黑屏。后来我学乖了,要么用 -ss 放在 -i 前面(先seek再解码),要么干脆重编码来保证精确截取。

# 精确截取(但会重编码)
ffmpeg -i input.mp4 -ss 10 -t 5 -c:v libx264 output.mp4

# 快速截取(可能不精确,但用copy)
ffmpeg -ss 10 -i input.mp4 -t 5 -c copy output.mp4

流复制 vs 重编码:一张图看懂

下面这张图,是我自己画的工作流程对比。你看完就明白了:

流复制 vs 重编码 工作流程对比 输入文件 流复制 (copy) 直接搬运 输出文件 重编码 解码 → 像素数据 重新编码压缩 输出文件 ✅ 速度快,无损,不改变编码 ❌ 速度慢,有损,可改变编码/分辨率 流复制适用场景 换封装、截取、合并、提取流 重编码适用场景 改分辨率/码率/编码格式、加滤镜

实际项目中的选择策略

我一般会这样决策:

  1. 先问自己:我需要改变视频内容吗? 如果不需要,直接copy。
  2. 如果需要改变,再问:能不能用硬件编码加速? 比如用 h264_nvench264_amf,速度能快很多。
  3. 如果对画质有极致要求,比如做母版归档,那就用 -crf 18 甚至无损模式重编码。
  4. 如果是批量处理,我习惯先跑一轮copy做预处理,把封装统一,再针对需要改内容的文件做重编码。

一个小技巧:ffprobe 先看看源文件的编码信息,确认是否支持copy。我经常遇到有人拿着MPEG-2的文件想copy到MP4里,结果播放器不认——这时候就得重编码了。

# 查看编码信息
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name input.mp4

嗯,总结一下:能用copy就别重编码,这是铁律。但该重编码的时候也别犹豫,毕竟有些活,copy真的干不了。


公众号:蓝海资料掘金营,微信deep3321