跳转至

04-概念总览:容器、编码、流、时间基、像素格式

目录页:见 FFmpeg 文档目录

这章解决一个初学者最容易卡住的问题:你明明会敲命令,但不知道自己在改什么

把 FFmpeg 的世界拆成 5 个核心概念,你就能把 80% 的命令行与排错串起来:

  1. 容器(container)
  2. 编码(codec)
  3. 流(stream)
  4. 时间(timestamp / timebase)
  5. 像素与颜色(pixel format / color)

1. 容器 vs 编码:不要把 mp4 当成 H.264

1.1 容器是什么

容器可以理解为“文件的包装盒”,它定义:

  • 里面可以装哪些流(视频/音频/字幕/章节/封面图…)
  • 索引、元数据、时间线怎么组织

常见容器:

  • MP4(.mp4
  • Matroska(.mkv
  • MPEG-TS(.ts
  • FLV(.flv

1.2 编码是什么

编码是“流内容的压缩/表示方式”:

  • 视频编码:H.264/AVC、H.265/HEVC、VP9、AV1…
  • 音频编码:AAC、MP3、Opus…
  • 字幕编码:SRT、ASS、WebVTT…

同一个容器可以装不同编码;同一个编码也能放进不同容器。

1.3 转封装 vs 转码

  • 转封装(remux):只换包装盒,不改内容 → 快、无损
  • 典型命令:-c copy
  • 转码(transcode):重新编码内容 → 慢、有损(但可改变码率/分辨率/格式)
  • 典型命令:-c:v libx264 / -c:a aac

你要先问自己:我到底要不要改“内容编码”?
如果不需要,就优先转封装。


2. 流(Stream):一份文件里可能有很多条“轨道”

一个媒体文件(容器)里可能同时有:

  • 多路视频(不同角度/不同码率)
  • 多路音频(中英双语)
  • 多路字幕(软字幕)
  • 附加数据(章节、封面图、metadata)

FFmpeg 处理时,最重要的能力之一是:选择你要处理的那条流

2.1 stream index 与 stream specifier

你会看到类似:

  • Stream #0:0(输入文件 0 的第 0 条流)
  • Stream #0:1(输入文件 0 的第 1 条流)

选择视频通常用:

  • -map 0:v:0(第一个输入的第一个视频流)

选择音频通常用:

  • -map 0:a:0(第一个音频流)
  • -map 0:a:m:language:eng(语言标签为 eng 的音频流)

2.2 map 的工程意义

初学者常见“我明明只想要视频,怎么出来还有音频/字幕”的根因是:

  • 没显式 -map,FFmpeg 用默认策略自动挑流

工程口径:一旦涉及多音轨/多字幕/多输入,尽量显式写 -map


3. 时间戳:PTS/DTS 到底是啥

3.1 PTS 与 DTS 的直觉

  • PTS(presentation timestamp):这帧应该在什么时候“展示”
  • DTS(decoding timestamp):这帧应该在什么时候“解码”

有 B 帧时,解码顺序与展示顺序可能不同,于是 PTS/DTS 会不一样。

3.2 time_base:时间戳不是秒

很多字段(尤其是 libav 里)存的不是秒,而是“tick”:

  • tick 的单位由 time_base 决定(一个分数 num/den

pts 转成秒的通用公式:

seconds = pts * time_base

初学者最容易踩的坑:

  • pts=90000 当成 90000 秒
  • 实际它可能是 time_base=1/90000,那就是 1 秒

3.3 CFR / VFR

  • CFR(constant frame rate):固定帧率
  • VFR(variable frame rate):可变帧率

很多“剪切后音画不同步”“抽帧不均匀”都和 VFR 有关。你要做的是:

  • 先用 ffprobe 判断是否 VFR
  • 需要统一时再转成 CFR

4. 像素格式与颜色:yuv420p / yuv444p / rgba 都是什么

4.1 pixel format:数据怎么存

常见视频像素格式:

  • yuv420p:最通用、兼容性最好(H.264/H.265 常见)
  • yuv422p / yuv444p:色度信息更多,体积更大
  • nv12:硬件解码/编码常见格式(半平面)

常见图像/渲染像素格式:

  • rgba / bgra

当你在命令里看到:

  • -pix_fmt yuv420p

它通常是在解决“设备/播放器兼容性问题”。

4.2 色度采样:4:2:0 是什么

直觉:

  • 亮度(Y)更重要,人眼更敏感
  • 色度(U/V)可以更低分辨率存储

yuv420p 典型就是:色度分辨率是亮度的一半再一半。

4.3 色彩空间/色彩范围(只要先记住这一句)

初学阶段记住一句工程口径就够:

  • 像素格式(怎么存)色彩空间(怎么解释颜色) 是两码事

如果你遇到“颜色发灰/偏色”,你需要进一步看:

  • color_primaries / color_trc / colorspace
  • color_range(full / limited)

这些字段都能用 ffprobe 查出来。


5. 编码质量与体积:CRF/码率/GOP/关键帧

5.1 码率(bitrate)

码率直觉:

  • 越高通常越清晰,也越大
  • 不同内容复杂度同码率的质量差很多

5.2 CRF(Constant Rate Factor)

对 x264/x265 来说,CRF 是最常用的“质量旋钮”:

  • 数值越小越清晰,体积越大
  • 常见起点:x264 用 18~23,x265 用 20~28(仅作直觉,不是标准答案)

5.3 GOP 与关键帧

GOP(Group Of Pictures)里包含:

  • I 帧(关键帧):能独立解码
  • P/B 帧:依赖前后帧预测

工程影响:

  • 剪辑/快进:关键帧更密集更好 seek,但体积更大
  • 直播/推流:通常要控制 keyframe 间隔(比如 2 秒一个关键帧)

6. FFmpeg 命令行:最小心智模型

一个你能一直复用的思路:

  1. 输入:-i ...
  2. 选择流:-map ...
  3. 处理(两类):
  4. 过滤器:-vf ... / -af ...(改变“内容”)
  5. 编码器参数:-c:v ... -crf ... -b:v ...(改变“压缩方式”)
  6. 输出容器:out.mp4 / out.mkv / out.ts

很多命令行“看起来很长”,本质就是 2/3 两步参数多。


7. 初学者常见误区(你可以用这张表自查)

  • 把 mp4 当编码:mp4 是容器,不是 H.264
  • 不知道文件里有多音轨:没看 ffprobe,也没用 -map
  • 一上来就 -c copy:无损很诱人,但遇到剪切/拼接/同步会很痛苦
  • 把 pts 当秒:一定要结合 time_base 看
  • 只看分辨率不看像素格式:兼容性问题多半出在 -pix_fmt yuv420p