3、推流核心原理:视频采集 → 编码 → 封装 → 推流
这一章,我们聊聊推流的完整链路。
说白了,就是把摄像头或屏幕的画面,经过压缩、打包,最后通过 RTSP PUT 命令发出去。我刚开始接触这个流程时,总觉得每一步都很神秘。后来亲手搭了一遍,才发现核心逻辑其实很清晰。
核心链路: 视频采集 → 编码(H.264/H.265)→ 封装(RTP/RTCP)→ 推流(RTSP PUT)
3.1 视频采集:从哪里拿到原始画面?
采集是整个流程的起点。你想想看,没有原始画面,后面编码、推流全是空谈。
常见的采集源有两种:
- 摄像头(Camera):通过 V4L2(Linux)或 DirectShow(Windows)驱动获取帧数据。我习惯用 V4L2,因为它稳定,而且支持多种像素格式。
- 屏幕(Screen):通过 X11、Wayland 或 Windows DXGI 抓取桌面画面。适合做录屏或直播。
采集到的原始数据通常是 YUV420P 或 RGB24。YUV 格式更常见,因为编码器直接吃它。
我的经验: 采集时一定要注意帧率控制。我曾经在项目中直接 while 循环读摄像头,结果 CPU 跑满,画面还卡顿。后来加了帧率限制(比如 30fps),问题就解决了。
3.2 编码:H.264 还是 H.265?
原始视频数据太大了。举个例子,1080p 的 YUV420P 一帧大约 3MB,30fps 就是 90MB/s。这带宽谁也扛不住。
所以必须编码压缩。H.264 和 H.265 是主流选择。
| 特性 | H.264 (AVC) | H.265 (HEVC) |
|---|---|---|
| 压缩率 | 基准 | 比 H.264 高 30%~50% |
| 计算开销 | 较低 | 较高(约 2~3 倍) |
| 兼容性 | 几乎所有设备支持 | 较新设备支持 |
| 码率控制 | CBR/VBR/CRF | CBR/VBR/CRF |
| 典型应用 | 直播、监控、视频通话 | 4K/8K 视频、高清直播 |
我个人习惯用 H.264 做直播,因为兼容性好,解码器遍地都是。H.265 虽然压缩率高,但编码器吃资源,推流端如果性能不够,反而会掉帧。
注意: 编码参数里,关键帧间隔(GOP)很重要。RTSP 推流一般设 2~3 秒一个关键帧。太长了,客户端拉流时等待时间长;太短了,码率会飙升。
3.3 封装:RTP 和 RTCP 在干什么?
编码后的数据是 NAL 单元(H.264)或 NAL 单元(H.265)。但网络传输不能直接扔 NAL 包,得用 RTP 协议封装。
RTP(Real-time Transport Protocol) 负责承载媒体数据。每个 RTP 包包含:
- 时间戳(Timestamp)—— 用于播放同步
- 序列号(Sequence Number)—— 用于丢包检测和排序
- 负载类型(Payload Type)—— 标识编码格式
- SSRC —— 同步源标识
RTCP(RTP Control Protocol) 负责控制信息。它不传媒体数据,而是传:
- 发送报告(SR)—— 统计发送的包数、字节数
- 接收报告(RR)—— 统计丢包率、抖动
- 应用自定义包(APP)—— 扩展用
说白了,RTP 是快递员,RTCP 是客服。快递员送货,客服反馈有没有丢件、延迟多少。
封装流程: NAL 单元 → 分片(如果太大)→ 添加 RTP 头 → 打包成 RTP 包 → 发送
H.264 的 NAL 单元大小不一。如果 NAL 单元超过 MTU(通常 1500 字节),就得分片打包。我遇到过一个问题:分片顺序错了,客户端解码直接花屏。后来加了序列号校验才解决。
3.4 推流:RTSP PUT 到底怎么用?
RTSP 协议里,推流用的是 PUT 方法。但注意,RTSP 本身不传媒体数据,它只负责建立和控制会话。真正的媒体数据是通过 RTP 传输的。
推流流程大致如下:
- 客户端发送
OPTIONS请求,确认服务器支持的方法 - 客户端发送
DESCRIBE请求,获取媒体描述(SDP) - 客户端发送
SETUP请求,建立传输通道(UDP 或 TCP) - 客户端发送
PUT请求,开始推流 - 客户端持续发送 RTP 包,服务器接收并转发
- 推流结束,发送
TEARDOWN请求关闭会话
避坑指南: 我曾经在 SETUP 阶段忘了指定传输模式(interleaved 或 UDP),结果服务器一直收不到数据。后来我统一用 TCP interleaved 模式,稳定多了。
下面是一个简化的 RTSP PUT 请求示例:
PUT rtsp://192.168.1.100:554/live/stream RTSP/1.0
CSeq: 4
Session: 12345678
Content-Type: application/x-rtp-stream
Content-Length: 1024
[RTP 数据包...]
注意,实际推流时,RTP 数据是持续发送的,不是一次性发完。服务器会持续接收直到收到 TEARDOWN。
3.5 整体流程回顾
把上面四步串起来,就是完整的推流链路:
- 采集:从摄像头或屏幕获取 YUV 帧
- 编码:用 H.264/H.265 压缩成 NAL 单元
- 封装:将 NAL 单元打包成 RTP 包,RTCP 负责反馈
- 推流:通过 RTSP PUT 命令发送 RTP 流到服务器
每一步都有坑,但核心逻辑不复杂。你只要把数据流想象成一条流水线:原材料进来,经过加工、包装,最后发货。嗯,就是这么回事。
一句话总结: 推流就是把原始画面压缩、打包、发出去。H.264 是主力,RTP 是载体,RTSP PUT 是命令。