3、FFmpeg核心概念:编解码器、封装格式、转码流水线、滤镜系统

做流媒体开发这么多年,我越来越觉得FFmpeg就像一把瑞士军刀。你想想看,从视频采集到推流播放,几乎每个环节都离不开它。但很多新手一上来就背命令行参数,结果换个场景就懵了。

我个人习惯是:先搞懂四个核心概念——编解码器、封装格式、转码流水线、滤镜系统。把这四个东西吃透了,FFmpeg就算入门了。

3.1 编解码器:视频的灵魂

编解码器,说白了就是压缩和解压缩的算法。视频原始数据太大了,不压缩根本没法传。H.264、H.265、VP8、VP9、AV1,这些都是编解码标准。

核心要点:编解码器决定视频的压缩效率和画质。H.264兼容性最好,H.265压缩率更高,AV1是开源新秀但编码慢。

我在项目中遇到过一个问题:用H.265编码的视频在老旧手机上播放不了。后来我学乖了,做WebRTC转码时,会根据客户端能力动态选择编码器。

编码器 压缩率 兼容性 典型场景
H.264 中等 极高 WebRTC、直播、点播
H.265 高 中等 4K/8K视频、存储
VP8 中等 高 WebRTC默认
VP9 高 中等 YouTube、Chrome
AV1 极高 低 下一代流媒体

小技巧:用 ffmpeg -encoders 可以查看你系统里支持的所有编码器。我经常用这个命令确认环境。

3.2 封装格式:视频的容器

封装格式是装视频、音频、字幕的容器。MP4、MKV、FLV、TS,这些都是封装格式。很多人把封装和编码搞混,其实它们是两码事。

举个例子:一个MP4文件里,视频可以是H.264编码,音频可以是AAC编码。封装格式只负责怎么把这些数据组织在一起,不关心具体怎么压缩。

注意:WebRTC不使用任何封装格式,它直接传输裸的RTP包。但转码后存文件或推流到CDN,就必须选封装格式了。

我曾经踩过一个坑:用FLV封装H.265视频,结果播放器死活不认。后来查资料才知道,FLV标准不支持H.265。嗯,封装格式和编码器是有兼容性限制的。

封装格式 适用场景 支持流式 常见编码
MP4 点播、移动端 否 H.264/H.265 + AAC
FLV 直播、RTMP 是 H.264 + AAC/MP3
TS HLS直播 是 H.264/H.265 + AAC
MKV 本地存储 否 几乎任何编码

3.3 转码流水线:数据怎么流动

转码不是一步到位的。FFmpeg内部有一条完整的流水线:解封装 → 解码 → 滤镜处理 → 编码 → 封装。每一步都有专门的模块负责。

我习惯用一张图来理解这个流程:

FFmpeg转码流水线 输入文件 解封装 解码 滤镜处理 编码 输出文件 封装 滤镜是可选的,不使用时直接编码

你看,数据从输入文件进来,先解封装拿到压缩的码流,然后解码成原始图像,经过滤镜处理(可选),再编码成目标格式,最后封装成输出文件。

关键点:解码后的数据是未压缩的YUV或RGB,占内存很大。滤镜操作就在这个阶段做。编码后再压缩回去。

实际项目中,这条流水线可以裁剪。比如只转封装不改编码,就可以跳过解码和编码两步,直接解封装后重新封装。FFmpeg会自动识别这种情况,效率很高。

# 完整转码:H.264 MP4 → H.265 MP4
ffmpeg -i input.mp4 -c:v libx265 -c:a copy output.mp4

# 仅转封装:不改编码,只改容器
ffmpeg -i input.mp4 -c copy output.ts

3.4 滤镜系统:视频的魔法

滤镜系统是FFmpeg最强大的部分。缩放、裁剪、旋转、加水印、调色、画中画,这些都能用滤镜实现。滤镜可以串联成链,也可以并联成图。

我刚开始用滤镜时,被它的语法搞晕过。后来发现规律了:滤镜用逗号串联,用分号并联。每个滤镜有自己的参数,用冒号分隔。

记忆口诀:逗号是串联(一个接一个做),分号是并联(同时做两路)。

举个例子,我要把一个视频缩放到720p,同时加上时间水印:

ffmpeg -i input.mp4 -vf "scale=1280:720,drawtext=text='%{pts}':fontsize=24:fontcolor=white:x=10:y=10" output.mp4

这里 scale 和 drawtext 用逗号串联,先缩放再加水印。顺序很重要,先缩放再加水印,水印位置是基于缩放后的画面算的。

我曾经犯过一个错:先加水印再缩放,结果水印文字被缩放得模糊不清。嗯,滤镜顺序直接影响最终效果。

滤镜名称 功能 常用参数
scale 缩放视频尺寸 width:height
crop 裁剪画面 out_w:out_h:x:y
drawtext 添加文字水印 text:fontsize:fontcolor
overlay 叠加图片/视频 x:y(位置)
fps 改变帧率 fps值

性能警告:滤镜操作在解码后的原始数据上进行,非常消耗CPU。特别是多个滤镜串联时,内存和CPU都会飙升。生产环境建议用GPU加速。

在WebRTC场景中,滤镜系统特别有用。比如服务端转码时,可以把接收到的视频流先降分辨率,再编码推给带宽低的客户端。或者给视频加上会议水印,标识来源。

好了,这四个核心概念讲完了。编解码器管压缩,封装格式管组织,转码流水管线流程,滤镜系统管处理。搞懂它们,FFmpeg就算入门了。后面我们会用这些知识做真正的WebRTC转码实战。