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内部有一条完整的流水线:解封装 → 解码 → 滤镜处理 → 编码 → 封装。每一步都有专门的模块负责。
我习惯用一张图来理解这个流程:
你看,数据从输入文件进来,先解封装拿到压缩的码流,然后解码成原始图像,经过滤镜处理(可选),再编码成目标格式,最后封装成输出文件。
关键点:解码后的数据是未压缩的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转码实战。