流媒体基础理论:视频编码原理(H.264/H.265)、音频编码原理(AAC/Opus)、封装格式(MP4/FLV/TS)
做流媒体开发,编码和封装是躲不开的两座山。很多人一开始就扎进WebRTC的API里,结果遇到花屏、音画不同步、推流失败,回头才发现是编码参数没搞对。这一章,我把视频编码、音频编码、封装格式的核心逻辑串一遍。不讲数学公式,只讲你写代码时真正需要知道的东西。
一句话总结本章:编码是压缩,封装是打包。H.264/H.265决定视频画质和码率,AAC/Opus决定音频清晰度和延迟,MP4/FLV/TS决定播放器能不能认出来。
2.1 视频编码:H.264 与 H.265
视频编码说白了就是「找重复」。一帧画面里,天空是蓝色的,下一帧天空还是蓝色的,那就只记一次变化。H.264和H.265都是干这个的,但思路不太一样。
2.1.1 H.264(AVC)—— 流媒体界的通用语言
H.264是目前兼容性最好的编码。从老式机顶盒到最新的Chrome浏览器,没有它不认识的。我个人习惯把H.264的编码结构拆成三层:
- GOP(Group of Pictures):一组画面。里面包含I帧、P帧、B帧。
- I帧:关键帧,完整的一张图。解码器从I帧开始才能看懂后面的帧。
- P帧/B帧:只记录变化的部分。P帧参考前面的帧,B帧参考前后两帧。
我在项目中遇到过一个问题:推流到RTMP服务器时,GOP设置太大(比如10秒一个I帧),播放器拖进度条后黑屏了十几秒。为什么?因为播放器没等到I帧,解码器一直卡着。后来我把GOP调成2秒,问题解决。
实战建议:WebRTC默认使用H.264,GOP建议设2-3秒。RTSP推流到FLV时,GOP不要超过5秒,否则首屏加载会慢。
2.1.2 H.265(HEVC)—— 省码率,但费设备
H.265比H.264压缩率提升约50%。同样画质,码率砍一半。代价是编码计算量翻倍。我记得第一次在树莓派上跑H.265编码,CPU直接飙到100%,画面卡成PPT。
H.265的核心改进在于:
- CTU(编码树单元):从H.264的16x16宏块扩展到最大64x64,大块区域压缩更狠。
- 帧内预测方向:从H.264的9种增加到33种,细节保留更好。
但要注意,WebRTC对H.265的支持还不完善。Chrome和Firefox默认不开H.265硬件编码。如果你做Web端推流,老老实实用H.264。如果是服务端转码或本地录制,H.265能省不少存储。
| 对比项 | H.264 | H.265 |
|---|---|---|
| 压缩率 | 基准 | 提升约50% |
| 计算复杂度 | 低 | 高(约2-4倍) |
| WebRTC支持 | 原生支持 | 部分浏览器需协商 |
| 适用场景 | 实时通信、直播 | 点播、本地存储 |
避坑指南:我曾经在RTSP转WebRTC项目里,直接用H.265推流,结果Safari能看,Chrome黑屏。后来加了SDP协商降级到H.264才搞定。如果你做跨平台,H.264永远是最稳的选择。
2.2 音频编码:AAC 与 Opus
音频编码比视频简单,但坑也不少。你想想看,视频花屏还能忍,音频一卡顿或者断断续续,用户直接关页面。
2.2.1 AAC —— 直播和点播的老大哥
AAC是MP4和FLV封装里的标准音频编码。它的采样率支持8kHz到96kHz,比特率从8kbps到320kbps。我在做RTMP推流时,几乎都用AAC-LC(Low Complexity),兼容性最好。
AAC的几个关键参数:
- 采样率:44100Hz或48000Hz。低于44100Hz,高频声音会丢失。
- 比特率:128kbps是平衡点。低于64kbps,人声会变「闷」。
- 声道:立体声还是单声道。WebRTC通常用单声道,节省带宽。
个人经验:有一次做远程医疗项目,医生抱怨听不清患者呼吸声。查了半天,发现AAC编码用了32kbps单声道,高频细节全丢了。换成48kbps后,问题解决。音频编码别省那点码率。
2.2.2 Opus —— WebRTC的默认选择
Opus是WebRTC的亲儿子。它支持可变比特率,从6kbps到510kbps,延迟低到2.5ms。相比之下,AAC最低延迟也要20ms左右。
Opus的优势在于:
- 动态码率调整:网络差时自动降码率,网络好时恢复。
- 丢包容忍:Opus内置PLC(丢包隐藏),丢包30%以内还能听清。
- 采样率自适应:从8kHz到48kHz无缝切换。
我记得有一次做跨国视频会议,网络抖动厉害。AAC编码下,丢包10%就开始出现「机器人声」。换成Opus后,丢包20%还能正常交流。这就是为什么WebRTC默认用Opus。
| 对比项 | AAC | Opus |
|---|---|---|
| 延迟 | 20-100ms | 2.5-60ms |
| 比特率范围 | 8-320kbps | 6-510kbps |
| 丢包处理 | 弱 | 强(内置PLC) |
| 封装兼容性 | MP4/FLV/TS | WebM/TS(FLV不支持) |
注意:FLV封装不支持Opus。如果你做RTMP推流(FLV格式),音频只能用AAC或MP3。WebRTC转RTMP时,必须做音频转码,否则推流失败。
2.3 封装格式:MP4、FLV、TS
编码是压缩,封装是打包。封装格式决定了播放器怎么读取音视频数据。我见过不少开发者把编码和封装搞混,比如问「MP4编码和H.264编码哪个好」——这俩不是一个层面的东西。
2.3.1 MP4 —— 点播之王
MP4是最通用的封装格式。它基于ISO Base Media File Format,内部用Box结构存储数据。MP4的优点是:
- 支持索引:快进快退不需要重新下载整个文件。
- 元数据丰富:可以存封面、字幕、章节信息。
- 广泛兼容:几乎所有播放器和浏览器都支持。
但MP4不适合直播。为什么?因为MP4的moov box(元数据)通常在文件末尾,播放器必须下载完整个文件才能开始播放。虽然可以用「faststart」参数把moov移到文件头,但直播场景下,你根本不知道文件什么时候结束。
2.3.2 FLV —— RTMP的专属格式
FLV是Adobe搞的格式,结构简单到粗暴:Header + 一堆Tag。每个Tag要么是视频,要么是音频,要么是脚本数据。RTMP协议传输的就是FLV格式的数据。
FLV的优点:
- 结构简单:解析快,延迟低。
- 支持直播:边推流边播放,不需要等待文件结束。
- 工具链成熟:FFmpeg、OBS、SRS都原生支持。
缺点也很明显:
- 不支持H.265:FLV规范里没有H.265的定义,虽然有些魔改版支持,但兼容性差。
- 不支持Opus:音频只能用AAC或MP3。
- 逐渐被淘汰:浏览器已经不再原生支持FLV,需要flv.js等库来播放。
2.3.3 TS —— 广电级封装
TS(Transport Stream)是MPEG-2标准的一部分,最初用于数字电视广播。它的核心特点是:
- 固定包长:每个包188字节,适合在不可靠信道传输。
- 支持多节目:一个TS流里可以包含多路音视频。
- 抗丢包:丢了一个包,不影响其他包的解析。
在WebRTC和RTSP融合场景里,TS常用于HLS直播。HLS就是把TS切片成一个个小文件,播放器逐个下载播放。我记得有一次做广电项目,要求推流到机顶盒,只能用TS封装,因为机顶盒的解码器只认TS。
| 封装格式 | 适用场景 | 支持H.265 | 支持Opus | 直播友好 |
|---|---|---|---|---|
| MP4 | 点播、本地录制 | 是 | 是(需WebM容器) | 否 |
| FLV | RTMP推流、直播 | 否 | 否 | 是 |
| TS | HLS、广电传输 | 是 | 是 | 是 |
2.4 知识体系总览
下面这张图把本章的核心知识点串起来了。你可以看到,视频编码和音频编码是独立的两条线,最终在封装格式里汇合。WebRTC和RTSP推流时,选择哪条路径,取决于你的目标播放器。
嗯,到这里,编码和封装的基础就讲完了。你可能会问:这些理论怎么用到WebRTC和RTSP融合里?别急,后面几章会手把手带你搭环境、写代码。先把这些概念刻在脑子里,后面遇到问题才能快速定位。