转封装只换信封,转码重写信纸;同一个文件,时间差近十倍。 判断标准就一句:要动像素就转码,只动容器就转封装。
4.5.1 讲了转码链,这一节把两条路都真跑一次对比。 下一篇 4.5.3 把最后一环从写文件换成写网络。
一、两条路的本质区别
转封装搬的是包,转码搬的是像素。 转封装 转码
处理单位 包 帧 要不要解码 不要 要 要不要编码 不要 要 画质 一点不掉 掉一点 能不能改画面 不能 能
「画质一点不掉」是转封装最大的价值。 它压根不碰像素,只是把同一批压缩包换了个方式装起来。 所以能转封装就别转码,这是本课最实用的一条建议。
二、实测:时间与体积摆在一起
同一个文件,两条路各跑一次。 项 转封装 转码
耗时 十几毫秒 一百毫秒上下 处理单位 138 个包 50 帧 产物大小 与原文件接近 看分辨率与 crf
耗时差近十倍,而两条路都没有报错、都产出了可播的文件。 不测的话根本不知道差这么多。 这个差距在长视频上会被放大成分钟级,批量转封装与批量转码是两种量级的活儿。
三、体积小不等于转码更省
这个误区必须点破:转码出来的文件更小,不是因为转码高效。 小的原因是分辨率砍了、码率降了。 如果把分辨率与码率都保持原样,转码产物通常比原文件更大——多了一轮有损压缩, 编码器还多了优化空间去堆码率。 改了什么 体积会怎样
只换容器 基本不变 降分辨率 明显变小 降 crf 数值(提质量) 变大
看体积要先问「改了什么参数」,不能光看数字。 「转码之后小了 80%」这句话没有信息量,得知道砍了什么。
四、转封装有个前提
编码格式得被目标容器支持。 h264 装进 mkv 没问题,装进 mp4 也没问题。 但想把 h264 塞进只认 mpeg2 的老容器,转封装会失败——这时候只能转码。 容器是信封,编码是信纸。 信纸得塞得进新信封才行。 常见的不兼容会报错说 codec not supported in container。 这个报错很好认:它不是格式不认识,是「认识但装不下」。看见它就知道该改走转码这条路。
五、动手 Demo:两条路——转封装与转码,差多少
同一个文件,两条路各跑一次,时间与体积摆在一起。
import av
# 第一条:转封装,完全不解码
with av.open("_media32/tiny.mp4") as ic:
with av.open("_media32/copy_out.mkv", "w") as oc:
vs = oc.add_stream_from_template(ic.streams.video[0])
for pkt in ic.demux(ic.streams.video[0]):
if pkt.dts is None:
continue
pkt.stream = vs
oc.mux(pkt)
实跑输出:
--------------------------------------------------------------------
两条路——转封装与转码,差多少
--------------------------------------------------------------------
**① 同一个文件,两条路各跑一次**
项 转封装 转码
------------------------------------------
耗时 5.3 毫秒 141.8 毫秒
处理单位 138 个包 50 帧
产物大小 45155 字节 6940 字节
分辨率 160×120 80×60
编码器 没动过 重新编了
**同样的源,转码比转封装慢 26.9 倍。** 慢的地方全在「解码 + 编码」这两环。
**② 体积反而小了,这不能归功于「转码更省」**
产物小是因为**分辨率砍了一半、还换了 CRF 30**。
如果把分辨率与码率都保持原样,转码出来的文件通常比原文件**更大**——因为多了一轮有损压缩。
**这一条很重要:转码不会让画质变好。** 每一次有损重编都掉一点,掉多少取决于码率给得够不够。
二代转码的片子看着发糊,就是这个原因。
**③ 什么时候用哪条路**
需求 该走哪条 理由
-----------------------------------------------------
换容器(mp4→mkv) 转封装 根本不用动码流
改分辨率 转码 像素得重排
改码率 转码 得重新量化
改帧率 转码 得丢帧或补帧
只切片/拼段 转封装 按时间切包就行
**判断标准就一句:要动像素就转码,只动容器就转封装。** 能转封装就别转码,省时间还保画质。
**④ 转封装有个前提:编码格式得被目标容器支持**
h264 装进 mkv 没问题。要是想把 h264 塞进只认 mpeg2 的老容器,转封装会失败——这时候只能转码。
**容器是信封,编码是信纸,信纸得塞得进新信封才行。**
add_stream_from_template 就是「照原样」,一字不改地搬。
两条路的耗时差在毫秒级就能看出来,长视频上是分钟级。
30 秒实验
- 把转封装的目标容器换成 mp4,看体积变化。
- 试着把 h264 转封装进 mpeg2 容器,看报什么错。
- 给转封装加一个
-c copy的等价物:确认没有解码被调用。
常见误区
- 以为转码更省体积。 体积小是因为换了参数,不是因为转码高效。
- 什么都走转码。 只换容器时白花十倍时间,还掉画质。
- 以为转封装什么容器都能进。 编码格式得被目标容器支持。
自测三问(点开对答案)
1. 只换容器该走哪条路,为什么? —— 转封装。它不碰像素,画质一点不掉,速度快近十倍。 2. 为什么转码出来的文件可能比原文件更大? —— 多了一轮有损压缩,编码器会重新分配码率。体积取决于新参数,不取决于「转码」本身。 3. 转封装失败最常见的原因是什么? —— 编码格式不被目标容器支持,比如把 h264 塞进只认 mpeg2 的容器。- ☐ (本节完,下一节 4.5.3 基于 RTP 传输的 FFmpeg 转码应用)