目录
1 RTSP
1.1 RTSP基本简介
一、RTSP 是什么?(定义与定位)
RTSP(Real Time Streaming Protocol) 是一个应用层协议,用于控制流媒体的播放行为。
类比生活场景:如果把流媒体比作 “自来水”,RTSP 就像是 “水龙头开关”,负责开启 / 暂停 / 调节水流,但不负责 “运输水”(数据传输由 RTP 负责)。
二、RTSP 的核心功能是什么?(四大控制命令)
RTSP 通过请求 - 响应模型实现以下操作:
- 建立会话(SETUP)
客户端告诉服务器:“我要播放这个视频,用 RTP/UDP 协议,我的接收端口是 5000-5001”。
服务器回应:“好的,我用 6000-6001 端口给你发数据,会话 ID 是 12345”。 - 播放控制(PLAY/PAUSE/TEARDOWN)
PLAY:开始传输媒体数据(通过 RTP)。
PAUSE:暂停播放,但保留会话。
TEARDOWN:关闭会话,释放资源。 - 查询信息(DESCRIBE)
客户端问:“这个视频的格式、编码是什么?”
服务器返回SDP 描述(如 H.264 编码、90000Hz 采样率)。 - 参数设置(GET/SET PARAMETER)
动态调整播放参数(如音量、码率)。
** HTTP 协议的核心区别**
对比维度 | RTSP | HTTP |
---|---|---|
协议方法 | 新增了 DESCRIBE、PLAY、SETUP、ANNOUNCE、RECORD 等方法 | 主要有 GET、POST、PUT 等方法 |
状态管理 | 是有状态协议,每个会话都有 session 概念 | 属于无状态协议 |
请求发起方 | 客户端和服务器端都能发送 Request 请求 | 只有客户端可以发送 Request 请求 |
数据传输方式 | 载荷数据一般通过带外方式传送(除交织情况),借助 RTP 协议在不同通道传输 | 载荷数据通过带内方式传送,例如请求的网页数据在回应消息体中携带 |
字符编码 | 使用 ISO 10646(UTF - 8),以适应 HTML 国际化需求 | 采用 ISO 8859 - 1 编码 |
URI 请求 | 请求时包含绝对 URI | 由于历史兼容性问题,请求中只包含绝对路径,主机名放在单独标题域 |
1.2 RSTP架构
RTSP 分为两种模式
UDP 模式(更常见)
RTSP 控制信令走 TCP(端口 554),保证可靠性。
RTP/RTCP 数据走 UDP(随机端口,如客户端 5000/5001,服务器 6000/6001)。
优势:低延迟,适合直播。
缺点:丢包风险高,需 RTCP 补偿。
TCP 模式(隧道模式)
所有数据(RTSP+RTP+RTCP) 都走 TCP 端口 554。
优势:穿透防火墙能力强(仅需开放一个端口)。
缺点:TCP 拥塞控制可能增加延迟。
深入剖析RTSP拉流客户端与服务器的完整交互流程
一、建立TCP连接(握手阶段)
目标:客户端与服务器建立可靠的控制通道(默认TCP 554端口)。
- 客户端发起TCP连接
Client → Server: SYN(源端口随机,目标端口554)
Server → Client: SYN+ACK
Client → Server: ACK
关键点:
- 此连接仅用于传输RTSP控制命令,不传输媒体数据。
- 后续所有RTSP请求/响应都通过此TCP通道发送。
二、OPTIONS请求(能力探测)
目标:客户端询问服务器支持哪些RTSP方法。
2.1 客户端发送OPTIONS请求
OPTIONS rtsp://example.com/stream.sdp RTSP/1.0
CSeq: 1
User-Agent: VLC/3.0.18 LibVLC/3.0.18
字段解析:
CSeq
:请求序列号,用于匹配响应。User-Agent
:客户端标识(如VLC播放器)。
2.2 服务器响应支持的方法
RTSP/1.0 200 OK
CSeq: 1
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER
关键点:
Public
字段列出服务器支持的RTSP方法(如PLAY
、PAUSE
)。- 客户端后续只能使用服务器明确支持的方法。
三、DESCRIBE请求(获取媒体描述)
目标:获取流媒体的技术参数(编码格式、时长等),以SDP格式返回。
3.1 客户端发送DESCRIBE请求
DESCRIBE rtsp://example.com/stream.sdp RTSP/1.0
CSeq: 2
Accept: application/sdp
字段解析:
Accept
:指定客户端期望的响应格式(此处为SDP)。
3.2 服务器返回SDP描述
RTSP/1.0 200 OK
CSeq: 2
Content-Type: application/sdp
Content-Length: 468
v=0
o=StreamingServer 3832474523 3832474524 IN IP4 192.168.1.100
s=Media Server
t=0 0
a=control:*
m=video 0 RTP/AVP 96 # 视频媒体行
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=42001F;sprop-parameter-sets=...
a=control:trackID=0
m=audio 0 RTP/AVP 97 # 音频媒体行
a=rtpmap:97 MPEG4-GENERIC/44100/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1408
a=control:trackID=1
SDP关键信息:
m=video
/m=audio
:媒体类型(视频/音频)。rtpmap
:载荷类型与编码映射(如96对应H.264)。fmtp
:编码参数(如H.264的profile-level-id)。control
:媒体流的控制URL(如trackID=0
)。
四、SETUP请求(建立传输通道)
目标:为每个媒体流(视频/音频)配置传输参数(协议、端口)。
4.1 客户端设置视频流传输
SETUP rtsp://example.com/stream.sdp/trackID=0 RTSP/1.0
CSeq: 3
Transport: RTP/AVP;unicast;client_port=5000-5001
Session: 12345678
字段解析:
Transport
:指定传输协议(RTP/AVP)、网络类型(unicast)和客户端端口(5000收RTP,5001收RTCP)。Session
:会话ID,由服务器在后续响应中分配。
4.2 服务器确认并分配端口
RTSP/1.0 200 OK
CSeq: 3
Transport: RTP/AVP;unicast;client_port=5000-5001;server_port=6000-6001
Session: 12345678;timeout=60
关键点:
- 服务器分配自己的端口(6000发RTP,6001发RTCP)。
timeout=60
:会话超时时间(60秒内无活动则关闭)。
4.3 客户端设置音频流传输(类似视频流程)
SETUP rtsp://example.com/stream.sdp/trackID=1 RTSP/1.0
CSeq: 4
Transport: RTP/AVP;unicast;client_port=5002-5003
Session: 12345678
五、PLAY请求(开始播放)
目标:命令服务器开始通过RTP发送媒体数据。
5.1 客户端请求播放
PLAY rtsp://example.com/stream.sdp RTSP/1.0
CSeq: 5
Session: 12345678
Range: npt=0.000- # 从0秒开始播放
字段解析:
Range
:播放范围(npt=0.000-
表示从头开始)。
5.2 服务器响应并提供RTP信息
RTSP/1.0 200 OK
CSeq: 5
Session: 12345678
RTP-Info: url=rtsp://example.com/stream.sdp/trackID=0;seq=12345;rtptime=67890,
url=rtsp://example.com/stream.sdp/trackID=1;seq=20000;rtptime=90000
关键点:
seq
:初始RTP序列号(用于排序)。rtptime
:初始RTP时间戳(用于同步音视频)。
六、媒体数据传输(RTP/RTCP)
目标:通过UDP传输音视频数据,并通过RTCP反馈质量。
6.1 RTP视频数据包(UDP 6000 → 5000)
[RTP Header]
- Version: 2
- Payload Type: 96 (H.264)
- Sequence Number: 12345
- Timestamp: 67890
- SSRC: 0x1234ABCD
[RTP Payload]
- H.264 NAL Unit (e.g., IDR frame, P frame)
6.2 RTCP接收报告(UDP 5001 → 6001)
[RTCP Header]
- Packet Type: 201 (Receiver Report)
- SSRC: 0xEF012345 (客户端标识)
[Report Block]
- SSRC of sender: 0x1234ABCD (对应RTP发送方)
- Fraction lost: 0.02 (2%丢包率)
- Cumulative packets lost: 5
- Interarrival jitter: 32ms
技术细节:
- RTP:通过序列号重组数据包,时间戳实现音视频同步。
- RTCP:每5秒左右发送一次,发送方根据丢包率调整码率。
七、控制命令与会话终止
7.1 PAUSE请求(暂停播放)
PAUSE rtsp://example.com/stream.sdp RTSP/1.0
CSeq: 6
Session: 12345678
RTSP/1.0 200 OK
CSeq: 6
Session: 12345678
关键点:暂停后,服务器保留会话状态,可通过PLAY
恢复。
7.2 TEARDOWN请求(终止会话)
TEARDOWN rtsp://example.com/stream.sdp RTSP/1.0
CSeq: 7
Session: 12345678
RTSP/1.0 200 OK
CSeq: 7
Session: 12345678; timeout=0
关键点:服务器关闭RTP/RTCP端口,释放资源。
拉流交互流程总结图
Client Server
| |
├─TCP Connect (554)────────────►|
| |
├─OPTIONS──────────────────────►|
|◄───────────200 OK─────────────┤
| |
├─DESCRIBE─────────────────────►|
|◄───────200 OK (SDP)───────────┤
| |
├─SETUP (video)────────────────►|
|◄───────200 OK (port 6000)─────┤
| |
├─SETUP (audio)────────────────►|
|◄───────200 OK (port 6002)─────┤
| |
├─PLAY─────────────────────────►|
|◄───────200 OK (RTP Info)──────┤
| |
▼ ▼
[RTP Data (UDP 6000→5000)] |
[RTCP Feedback (UDP 5001→6001)] |
| |
├─PAUSE/PLAY/TEARDOWN──────────►|
|◄───────────200 OK─────────────┤
推流流程(Client → Server 发送数据)
- 第一步:OPTION:客户端向服务器查询可用方法,服务器在响应的 public 头字段中返回所有可用方法,如 OPTIONS、DESCRIBE、SETUP 等。
- 第二步:ANNOUNCE:客户端向服务器发送媒体描述信息(SDP 格式),服务器响应并返回 Session ID。
- 第三步:SETUP:客户端通过 Transport 头字段列出可接受的传输选项(如 RTP/UDP 端口),请求建立会话,服务器返回选定的传输选项和 Session ID。
- 第四步:RECORD:客户端请求服务器开始传输数据。
- 第五步:RTP 数据推送:客户端通过 RTP 协议向服务器发送音视频数据,同时可能伴随 RTCP 控制包。
- 第六步:TEARDOWN:客户端请求关闭会话,服务器确认响应。
1.3 重点内容分析
1. 基础概念类
- 问题 1:RTSP 的主要作用是什么?与 RTP/RTCP 的关系是什么?
- 回答:RTSP 主要用于建立和控制媒体流会话,像 OPTION、SETUP、PLAY 等方法用于协商传输参数,而媒体数据实际通过 RTP 传输,RTCP 则用于监控传输质量和同步。
- 问题 2:Session ID 和 SSRC 的区别是什么?分别由谁生成?
- 回答:Session ID 是会话标识,由服务器在 ANNOUNCE 或 SETUP 响应中生成,客户端后续请求需携带该 ID;SSRC(同步源标识符)用于标识 RTP 流的来源,推流时由客户端自定义,拉流时由服务器在 SETUP 响应中返回。
- 问题 3:Transport 头字段的作用是什么?常见参数有哪些?
- 回答:该字段用于协商传输协议和端口,客户端在请求中列出可选方案(如 RTP/UDP、客户端端口范围),服务器在响应中选定实际参数(如服务器端口、SSRC)。常见参数包括协议类型(RTP/AVP)、传输方式(unicast/multicast)、端口范围(client_port/server_port)、模式(record/play)等。
2. 流程与协议对比类
- 问题 1:推流和拉流的核心流程差异有哪些?
- 回答:
- 第二步不同:推流使用 ANNOUNCE 发送媒体描述,拉流使用 DESCRIBE 获取媒体描述。
- 第四步不同:推流通过 RECORD 请求发送数据,拉流通过 PLAY 请求接收数据。
- RTP 方向不同:推流是客户端到服务器,拉流是服务器到客户端。
- 回答:
- 问题 2:RTSP 为什么被称为“带外控制协议”?
- 回答:因为 RTSP 的控制信令(如 SETUP、PLAY)和媒体数据(RTP 流)通过不同通道传输,控制信令通常在 RTSP 连接中传输,媒体数据通过独立的 RTP/RTCP 通道传输,所以是“带外”方式。
- 问题 3:RTSP 能否基于 TCP 传输?实际应用中如何选择传输协议?
- 回答:RTSP 协议本身可基于 TCP 或 UDP 传输,默认使用 UDP(效率高、适合实时流)。若网络环境复杂(如防火墙限制),可改用 TCP 传输控制信令和媒体数据,但会增加延迟。文档中推流和拉流示例均使用 UDP(Transport: RTP/AVP/UDP)。
2 RTR
2.1 RTR简介
一、RTP协议的定位与核心作用
RTP(Real-Time Transport Protocol)是专为实时媒体流传输设计的网络传输协议,属于OSI 模型的传输层,但通常与应用层结合使用。其核心作用包括:
- 媒体数据封装:将音频、视频等实时数据封装为适合网络传输的数据包。
- 时序控制:通过序列号和时间戳确保数据包按顺序重组和媒体同步。
- 多源标识:支持多播和单播场景,标识不同数据来源(如多个摄像头或麦克风)。
RTP不保证传输可靠性,也不提供流量控制或拥塞控制,通常与 UDP 协议结合使用,利用 UDP 的低延迟特性实现快速传输**,而可靠性由上层协议(如 RTCP)补偿。**
二、RTP报文格式与关键字段解析
RTP报文由 12字节固定报头 和 有效载荷 组成,报头结构如下:
字段 | 长度 | 功能描述 |
---|---|---|
版本号(V) | 2位 | 当前协议版本为2,用于协议兼容性判断。 |
填充标志(P) | 1位 | 若P=1,报文尾部包含填充字节,非有效载荷内容,用于对齐数据。 |
扩展标志(X) | 1位 | 若X=1,报头后跟随一个扩展报头,用于自定义协议扩展。 |
CSRC计数器(CC) | 4位 | 指示CSRC标识符的数量(0~15),用于标识混合流中的原始信源。 |
标记位(M) | 1位 | 含义由具体应用定义,如视频中标识帧结束(I帧),音频中标识帧开始。 |
有效载荷类型(PT) | 7位 | 标识载荷数据格式(如H.264=96,AAC=101),接收方据此选择解码器。 |
序列号 | 16位 | 每发送一个报文递增1,用于检测丢包和重组数据顺序。 |
时间戳(Timestamp) | 32位 | 反映采样时刻,单位为时钟频率(如90kHz),用于计算延迟和同步音视频。 |
同步信源(SSRC) | 32位 | 唯一标识数据源(如摄像头、麦克风),随机生成,同一会话中不重复。 |
特约信源(CSRC) | 32位×n | 混合流场景中,记录原始信源的SSRC列表(n≤15),由混合器插入。 |
示例代码结构(C语言):
typedef struct _rtp_header_t {
uint32_t v:2; // 版本号
uint32_t p:1; // 填充标志
uint32_t x:1; // 扩展标志
uint32_t cc:4; // CSRC计数器
uint32_t m:1; // 标记位
uint32_t pt:7; // 有效载荷类型
uint32_t seq:16; // 序列号
uint32_t timestamp; // 时间戳
uint32_t ssrc; // 同步信源
} rtp_header_t;
三、同步信源(SSRC)与特约信源(CSRC)的区别
同步信源(SSRC)
- 定义:直接产生媒体流的信源,如麦克风、摄像机或RTP混合器本身。
- 作用:接收方通过SSRC区分不同数据源,同一会话中每个SSRC唯一。
- 示例:视频会议中,每个参会者的摄像头对应一个独立的SSRC。
特约信源(CSRC)
- 定义:当混合器(如视频会议服务器)合并多个信源的流时,将原始信源的SSRC记录为CSRC,混合器自身的SSRC作为新流的标识。
- 作用:接收方通过CSRC表了解混合流的来源组成。
- 示例:三路音频流(SSRC1、SSRC2、SSRC3)经混合器生成新流(SSRC4),混合后的RTP包中CSRC字段记录SSRC1-3,便于接收方识别原始发言者。
混合流程示意图:
SSRC1(音频1) ──►
SSRC2(音频2) ──► 混合器 ──► 新流(SSRC4,CSRC=[SSRC1, SSRC2])
SSRC3(视频) ──►
四、RTP的工作流程(发送端与接收端)
发送端处理
- 上层应用(如编码器)将媒体数据(如H.264帧、AAC音频块)传递给RTP模块。
- RTP模块添加报头(设置序列号、时间戳、SSRC等),封装为RTP报文。
- 通过Socket接口选择UDP协议发送,目标端口由传输协议(如RTSP)协商确定。
接收端处理
- 通过Socket接收RTP报文,分离报头与载荷。
- 解析报头:
- 用序列号检测丢包,重组乱序包。
- 用时间戳计算延迟抖动,同步音视频流。
- 根据SSRC/CSRC区分数据源,分发至不同解码器。
- 将载荷数据传递给上层应用(如解码器)进行后续处理。
五、RTP的典型应用场景
视频会议(如WebRTC)
- 每个参会者的音视频流分配独立SSRC,混合器通过CSRC记录多源信息。
- 时间戳用于唇音同步,序列号处理网络抖动导致的包乱序。
实时直播(如RTSP/RTP流)
- 服务器通过RTP发送H.264视频和AAC音频,客户端根据PT字段选择解码器。
- RTCP周期性反馈丢包率,发送端动态调整码率(如降低分辨率)。
监控系统
- 多个摄像头的流通过不同SSRC标识,接收端按源分离画面。
- 支持多播传输,减少服务器负载。
六、RTP与RTCP的协同工作
RTP负责数据传输,而 RTCP(RTP控制协议) 负责监控传输质量并反馈:
- RTCP功能:
- 发送端发送 SR(发送报告),包含已发送包数、字节数、时间戳等。
- 接收端发送 RR(接收报告),包含丢包率、抖动、最后接收时间等。
- 通过SSRC/CSRC关联RTP流与参与者身份(如用户名)。
- 协同机制:
- 发送端根据RR调整编码参数(如降低码率应对高丢包)。
- 接收端利用SR中的时间戳实现跨流同步(如音频与视频对齐)。
总结:RTP的核心价值
RTP通过轻量化报头设计和时序控制机制,在实时性与可靠性之间取得平衡,成为音视频流媒体的基础协议。其核心优势包括:
- 多源支持:SSRC/CSRC灵活标识单播、多播和混合流场景的数据源。
- 低延迟传输:依赖UDP,适合实时互动场景(如直播、视频会议)。
- 扩展性:通过扩展标志(X)和载荷类型(PT)适配多种编码格式(H.264、VP9、Opus等)。
理解RTP报文结构与工作流程,是深入学习WebRTC、RTMP、RTSP等上层协议的基础。
2.2 RTP 封装 H.264
一、封包核心目标与前提条件
RTP 封装 H.264 的目标是将 H.264 编码后的 NALU 单元(Network Abstraction Layer Unit)按照 RTP 协议规范进行打包,以便在网络中传输。
前提条件:
已获取 H.264 编码器输出的原始 NALU 流(包含 SPS/PPS、IDR 帧、P 帧等)。
确定 RTP 载荷类型(PT),通常为 96-127 之间的数值(需与接收端协商一致)。
二、H.264 NALU 分类与特性
H.264 的 NALU 按类型可分为三大类,封装时需区别对待:
1. 关键参数集(Type=7/8):
- SPS(序列参数集):包含编码级别、分辨率、帧率等全局参数。
- PPS(图像参数集):包含熵编码模式、片组等图像级参数。
- 处理方式:通常单独封装为 RTP 包,或与 SEI(补充增强信息)聚合封装。
2. 视频编码数据(Type=1/5)
- IDR 帧(Type=5):关键帧,解码必须从 IDR 帧开始。
- P 帧 / B 帧(Type=1):预测帧,依赖前面的帧解码。
- 处理方式:根据大小选择单 NALU 模式或分片模式。
3. 辅助数据(Type=6)
- SEI(补充增强信息):包含时间码、用户数据等辅助信息。
- 处理方式:通常与 SPS/PPS 聚合封装,或单独封装。
三、RTP 封装模式选择
1. 单 NALU 模式(Single NAL Unit)
适用场景:NALU 长度 ≤ MTU(通常 1460 字节,MTU=1500-IP 头 20-UDP 头 8)。
RTP Header (12字节) + NALU Header (1字节) + NALU Data
关键步骤:
- 创建 RTP 报头,设置序列号(递增)、时间戳(基于采样时刻)、SSRC(随机生成)。
- 将完整 NALU 作为 RTP 载荷(数据包),直接添加到报头后。
- 设置 RTP 标记位(M): 若为 IDR 帧的最后一个分片,M=1;否则 M=0。
2. 分片模式(Fragmentation Unit, FU)
适用场景:NALU 长度 > MTU,需拆分为多个 RTP 包。
分片类型:
- FU-A(Type=28):无依赖的分片,常用。
- FU-B(Type=29):带时间戳的分片,适用于低延迟场景。
FU-A 封装格式:
RTP Header + FU Indicator (1字节) + FU Header (1字节) + NALU Fragment
- FU Indicator:
前 3 位:NALU 头的 F(禁止位)和 NRI(重要性指示)。
后 5 位:固定值 28(表示 FU-A 类型)。 - FU Header:
第 1 位(S):起始位,1 表示当前是 NALU 的第一个分片。
第 2 位(E):结束位,1 表示当前是 NALU 的最后一个分片。
第 3 位(R):保留位,必须为 0。
后 5 位:原始 NALU 的 Type 字段(如 5 表示 IDR 帧)。
分片步骤:
- 计算可承载的最大数据长度(MaxSize = MTU - RTP 头 - FU Indicator - FU Header)。
- 首个分片(S=1):
FU Indicator = (NALU[0] & 0xE0) | 28
FU Header = 0x80 | (NALU[0] & 0x1F)
载荷 = FU Indicator + FU Header + NALU Data [1:MaxSize] - 中间分片(S=0, E=0):
FU Indicator = (NALU[0] & 0xE0) | 28
FU Header = 0x00 | (NALU[0] & 0x1F)
载荷 = FU Indicator + FU Header + NALU Data [偏移量:偏移量 + MaxSize] - 最后分片(E=1):
FU Indicator = (NALU[0] & 0xE0) | 28
FU Header = 0x40 | (NALU[0] & 0x1F)
载荷 = FU Indicator + FU Header + NALU 剩余数据
3. 聚合包模式(Aggregation Packet)
适用场景:多个小 NALU(如 SPS+PPS+SEI)合并为一个 RTP 包,减少开销。
四、RTP 时间戳与序列号管理
- 时间戳生成:
单位:90kHz(即 1 秒 = 90000 个时间戳单位)。
计算方法:Timestamp = 采样时间(秒) × 90000。
示例:25fps 视频,每帧间隔 = 90000/25=3600 时间戳单位。 - 序列号管理:
初始值随机生成,后续每发送一个 RTP 包递增 1。
溢出处理:16 位序列号范围 0-65535,溢出后自动回绕(如 65535→0)。
五、封包流程总结
- NALU 分类:
分离 SPS/PPS/SEI、IDR 帧、P 帧 / B 帧。
检查 NALU 长度,决定使用单 NALU、分片或聚合模式。 - 构建 RTP 报头:
设置版本(V=2)、填充位(P=0)、扩展位(X=0)、CSRC 计数(CC=0)。根据 NALU 类型设置标记位(M)。分配序列号和时间戳。 - 选择封装模式:
小 NALU(≤MTU):单 NALU 模式。
大 NALU(>MTU):分片模式(FU-A)。
多个小 NALU:聚合模式(STAP-A)。 - 发送 RTP 包:
通过 UDP 套接字发送,目标地址和端口由 RTSP 协商确定。
2.3 RTP 解封装 H.264
一、解封装核心目标与前提条件
RTP 解封装 H.264 的目标是从 RTP 数据包中提取完整的 H.264 NALU 单元,恢复为编码器输出的原始格式,供后续解码使用。
- 已知 RTP 载荷类型(PT)为 H.264 对应的数值(如 96)。
- 解析 RTP 报头中的序列号(Seq)和时间戳(Timestamp),用于重组和同步。
二、解封装关键步骤
1. 解析 RTP 报头与载荷类型判断
- 提取 RTP 固定头:获取版本号(V=2)、标记位(M)、序列号、时间戳等字段。
- 判断载荷类型(PT):若 PT=96(H.264 默认 PT 值),则进入 H.264 解封装流程。
- 检查标记位(M):对于视频流,M=1 通常表示 NALU 结束(如 IDR 帧的最后一个分片)
2. 识别 NALU 打包模式
H.264 的 RTP 打包有三种模式,解封装需先判断当前数据包属于哪种模式
- 单 NALU 模式(Single NAL Unit):
RTP 载荷直接对应一个完整 NALU,格式为:
RTP Header + NALU Header(1字节) + NALU Data
识别方法:NALU 头的 Type 字段为 1-23 或 24-29(需结合实际载荷长度)。
处理方式:直接提取载荷作为完整 NALU,无需重组。
- 聚合包模式(STAP/MTAP)
一个 RTP 包包含多个 NALU(如 SPS、PPS、SEI 组合),格式为:
RTP Header + [NALU1 + NALU2 + ... + NALUn]
识别方法:NALU 头的 Type 为 24(STAP-A)、25(STAP-B)等聚合类型。
处理方式:按 NALU 边界(如起始码 0x000001 或 0x00000001)拆分多个 NALU。
- 分片模式(FU-A/FU-B):
大 NALU 被拆分为多个 RTP 包,需重组,格式为:
RTP Header + FU Indicator(1字节) + FU Header(1字节) + NALU Fragment
识别方法:NALU 头的 Type 为 28(FU-A)或 29(FU-B)。
处理方式:根据序列号缓存分片,按 S/E 标志组合成完整 NALU
3. 分片 NALU 的重组(以 FU-A 为例)
- 解析 FU Indicator 和 FU Header:
- FU Indicator:前 3 位为 NALU 头的 F 和 NRI,后 5 位固定为 28(FU-A 类型)。
- FU Header:
S 位(开始位):1 表示当前分片是 NALU 的起始部分。
E 位(结束位):1 表示当前分片是 NALU 的结束部分。
Type:原始 NALU 的类型(如 5 表示 IDR 帧)。
- 重组逻辑:
创建缓存队列:以序列号为键,存储同一 NALU 的所有分片。- 处理首个分片(S=1):
提取 FU Header 中的 Type,构造完整 NALU 头(F+NRI+Type)。
将 FU 载荷作为 NALU 数据的起始部分。 - 处理中间分片(S=0, E=0):直接追加载荷到对应 NALU 数据。
- 处理最后分片(E=1):追加载荷并标记 NALU 完整,触发解封装完成。
- 处理首个分片(S=1):
示例:IDR 帧分片重组
首个分片(S=1, E=0):
FU Indicator=0x7C(二进制 01111100),FU Header=0x85(二进制 10000101)
→ 完整 NALU 头 = 0b01100101(0x65,对应 IDR 帧类型 5)。
中间分片(S=0, E=0):FU Header=0x05(二进制 00000101)→ 直接追加数据。
最后分片(S=0, E=1):FU Header=0x45(二进制 01000101)→ 组合完成 NALU。
4. 恢复 NALU 原始格式
去除 RTP 相关字段:
单 NALU 模式直接使用载荷中的 NALU Header 和 Data;分片模式重组后需确保 NALU 头正确(F、NRI、Type)。
补充起始码:
H.264 裸流通常以起始码(0x000001 或 0x00000001)标识 NALU 边界,解封装后需在每个 NALU 前添加起始码,供解码器识别。
5. 时间戳与同步处理
- 时间戳提取:从 RTP 报头的 Timestamp 字段获取采样时刻,单位为 90kHz(如 Timestamp=67890 表示 754.33ms)。
- 同步机制:
同一 NALU 的所有分片共享相同时间戳。
音频与视频流通过 RTCP 的 SR/RR 报告进行跨流同步。
三 解封装与解码的衔接
解封装后的 NALU 流需按以下步骤交付解码器:
- 排序 NALU:按序列号和时间戳顺序排列,确保解码顺序正确。传递给 H.264 解码器:
- 解码器输入要求:NALU 流以起始码分隔,包含 SPS/PPS(解码必需参数集)。
示例流程:
解封装得到NALU列表 → 检查是否包含SPS/PPS(Type=7/8)→ 按顺序送入解码器 → 输出YUV视频帧
2.4 RTP封装 AAC
一、AAC封装到RTP的核心逻辑
AAC音频流在RTP中的封装需遵循 RFC3640 规范,核心步骤是去除ADTS头并添加RTP特定格式的头部信息。
1. 封装前的准备:解析AAC原始数据
ADTS头处理:
AAC原始数据通常包含7字节的ADTS头(或9字节,含CRC校验),封装时需跳过该头部,仅保留音频载荷。- ADTS头包含采样率、通道数等信息,但RTP传输中这些参数通过SDP协商,因此无需保留。
载荷类型(PT)协商:
通过SDP确定RTP的PT值(如97),并配置相关参数(如a=rtpmap:97 mpeg4-generic/44100
)。
2. RTP封装步骤(单AU模式)
步骤1:构建RTP头
- 设置版本(V=2)、序列号(Seq)、时间戳(Timestamp,单位90kHz)、SSRC等字段。
- 时间戳计算:根据采样率确定每帧时间戳增量。例如,44.1kHz采样的AAC,每帧1024样本对应时间戳增量为
(1024/44100)×90000≈2097
。
步骤2:添加AU头信息
RTP载荷由以下部分组成(以单AU为例):
RTP Header (12B) + AU-headers-length (2B) + AU-header (2B) + AAC Payload (去除ADTS后的数据)
- AU-headers-length:表示后续AU-header的总位数,单AU时为16位(2字节)。
bytes[0] = 0x00; // 高位 bytes[1] = 0x10; // 低位(16位=2字节)
- AU-header:高13位表示AU载荷长度,低3位保留。
uint16_t au_size = payload_length; // 去除ADTS后的AAC数据长度 bytes[2] = (au_size >> 5) & 0x1F; // 高13位的前8位 bytes[3] = (au_size & 0x1F) << 3; // 高13位的后5位,左移3位补零
步骤3:组合载荷数据
将AU头与AAC载荷拼接,作为RTP的净荷部分。例如,去除ADTS后的AAC数据为200字节,则载荷结构为:
[RTP头12B] [0x0010] [0x0640] [AAC数据200B]
0x0640
对应AU-header的13位长度值0b0000011001000
(十进制200)。
3. 多AU封装与参数配置
若一个RTP包包含多个AU(如连续音频帧),需扩展AU-header数组:
- AU-headers-length:总位数为
n×16
(n为AU数量)。 - AU-header:每个AU对应一个header,包含
AU-size
和AU-Index-delta
(序号增量)。 - SDP参数:需通过
fmtp
字段声明sizeLength=13
(AU-size占13位)、indexLength=3
等。a=fmtp:97 streamtype=5; profile-level-id=1; config=1288; sizeLength=13; indexLength=3;
2.5 RTP解封装AAC
解封装是封装的逆过程,目标是从RTP包中恢复原始AAC帧(带ADTS头)。
一 解封装流程
1. 解析RTP头与载荷结构
- 验证PT值:确认PT为AAC对应的动态类型(如97)。
- 提取载荷:从RTP包中分离出
AU-headers-length
、AU-header
和AAC Payload
。
2. 解析AU头信息
步骤1:读取AU-headers-length
- 取值为16表示单AU,32表示双AU,依此类推。
- 计算AU数量:
(au_headers_length / 8) / 2 = n
。
步骤2:解析AU-header
- 提取每个AU的大小(高13位)和序号(低3位)。
uint16_t au_header = (bytes[2] << 8) | bytes[3]; uint13_t au_size = (au_header >> 3) & 0x1FFF; // 高13位
步骤3:分离AAC载荷
根据au_size
从载荷中拆分出每个AU的数据块,例如单AU时直接取前au_size
字节。
3. 恢复ADTS头并输出
- 构建ADTS头:需包含采样率、通道数等信息,可从SDP的
config
字段解析。- 示例:
config=1288
对应audioObjectType=2
(AAC LC)、samplingFrequencyIndex=7
(22050Hz)、channelConfiguration=1
(单声道)。
- 示例:
- 组合完整AAC帧:
ADTS Header (7B) + AAC Payload (从RTP提取的AU数据)
二 关键参数与SDP配置
SDP中的AAC参数:
m=audio 0 RTP/AVP 97 a=rtpmap:97 mpeg4-generic/44100 a=fmtp:97 streamtype=5; profile-level-id=1; config=1408; sizeLength=13;
config
:前两字节为AudioSpecificConfig,包含编码参数。sizeLength=13
:AU-size占13位,最大支持8191字节(2^13-1)。
时间戳同步:
- 接收端根据RTP时间戳计算播放时间,如时间戳增量2097对应44.1kHz的1024样本帧(
2097 = 90000×1024/44100
)。
- 接收端根据RTP时间戳计算播放时间,如时间戳增量2097对应44.1kHz的1024样本帧(
错误处理:
- 若
AU-headers-length
非16的倍数,视为无效包,触发丢包重传机制(通过RTCP反馈)。
- 若
总结:封装与解封装的核心差异
阶段 | 核心操作 | 文档关联段落 |
---|---|---|
封装 | 去除ADTS头,添加RTP头和AU头,按SDP配置填充参数 | 、 |
解封装 | 解析RTP头和AU头,恢复ADTS头,重组完整AAC帧 | 、 |
参数协商 | 通过SDP传递PT值、采样率、通道数等,确保两端兼容 | 、 |
3 SDP
3.1 基础概念
一、SDP基础概念
1. 协议定位与用途
- 定义:SDP(Session Description Protocol,会话描述协议)是一种文本格式的应用层协议,用于描述多媒体会话的参数(如媒体类型、编码格式、传输地址等),但不负责传输控制,需与RTSP、SIP等协议结合使用。
- 核心作用:
- 在RTSP中用于传递媒体描述信息(如推流/拉流时的SDP协商);
- 在WebRTC中用于交换音视频编解码器、网络地址等连接参数。
- 特点:基于文本、可扩展,字段采用
<类型>=<值>
格式,类型为单个字符(如v=
、m=
),值为结构化文本。
2. 与RTSP的关系
- RTSP负责会话控制(如SETUP、PLAY命令),SDP负责媒体描述(如编码格式、端口);
- RTSP通过ANNOUNCE/DESCRIBE方法传递SDP内容,实现媒体协商。
二、SDP核心结构与语法
1. 整体结构
SDP分为会话级参数和媒体级参数,前者作用于整个会话,后者针对单个媒体流(如音频、视频):
会话级参数(必填在前)
v= 协议版本号
o= 会话源
s= 会话名称
t= 会话时间
可选字段(如c=连接信息、a=属性)
媒体级参数(每个媒体流以m=开始)
m= 媒体类型、端口、协议、格式
可选字段(如a=属性、c=连接信息)
- 会话级与媒体级的分界:第一个
m=
字段出现前为会话级,之后为媒体级。
2. 必需字段(必填项)
字段 | 格式与含义 | 示例 |
---|---|---|
v= | 协议版本号,当前固定为0 |
v=0 |
o= | 会话源信息,包含6个子字段:用户名、会话ID、版本、网络类型、地址类型、地址 | o=- 1271659412 1271659412 IN IP4 10.56.136.37 |
s= | 会话名称,不能为空(无意义时可填空格) | s=Demo Meeting |
t= | 会话时间,格式为开始时间 结束时间 (0 0 表示永久有效) |
t=0 0 |
m= | 媒体描述,包含4个子字段:媒体类型、端口、传输协议、格式列表 | m=video 45678 RTP/AVP 96 (视频流,端口45678,RTP协议,格式96) |
3. 可选字段(扩展信息)
字段 | 作用范围 | 含义 | 示例 |
---|---|---|---|
c= | 会话/媒体级 | 连接信息(网络类型、地址类型、地址) | c=IN IP4 192.168.1.100 (IP4地址) |
a= | 会话/媒体级 | 附加属性(如编码参数、传输控制) | a=rtpmap:96 H264/90000 (格式96对应H264,时钟速率90000) |
b= | 会话/媒体级 | 带宽信息(单位kbit/s) | b=AS:24 (音频带宽24kbit/s) |
u= | 会话级 | 会话相关URI地址 | u=http://example.com/session |
三、关键字段详解
1. 媒体描述字段(m=)
- 格式:
m=<媒体类型> <端口> <传输协议> <格式列表>
- 媒体类型:
audio
(音频)、video
(视频)、application
(应用数据)等; - 传输协议:常见
RTP/AVP
(基于UDP的RTP)、TCP
等; - 格式列表:RTP负载类型(如
0
对应G.711音频,96
对应动态H264视频)。
- 媒体类型:
- 示例:
m=audio 45678 RTP/AVP 0 15 3 // 音频流,端口45678,支持G.711(0)、G.728(15)、GSM(3) m=video 0 RTP/AVP 96 // 视频流,端口未确定(0表示待协商),格式96(需a=rtpmap补充说明)
2. 附加属性字段(a=)
- 作用:扩展媒体参数或会话行为,分为特征属性(如
sendonly
)和值属性(如rtpmap
)。 - 常见类型:
- 编码格式说明:
a=rtpmap:<负载类型> <编码名>/<时钟速率>
a=rtpmap:96 H264/90000 // 负载类型96对应H264,时钟速率90000Hz
- 传输控制:
a=control:streamid=0
(指定媒体流ID,用于多流场景); - 方向控制:
a=sendonly
(只发送不接收)、a=recvonly
(只接收不发送)。
- 编码格式说明:
3. 连接信息字段(c=)
- 格式:
c=<网络类型> <地址类型> <连接地址>
- 网络类型:固定为
IN
(Internet); - 地址类型:
IP4
或IP6
; - 连接地址:单播地址(如
192.168.1.100
)或组播地址(如224.2.36.42
)。
- 网络类型:固定为
- 示例:
c=IN IP4 0.0.0.0 // 会话级连接地址(0.0.0.0表示未指定,由媒体级字段覆盖)
3.2 SDP协议示例解析
示例1:Helix流媒体服务器的SDP(RTSP场景)
v=0 // 版本号
o=- 1271659412 1271659412 IN IP4 10.56.136.37 // 会话源(用户名-,会话ID重复,IP地址10.56.136.37)
s=<No title> // 会话名称
c=IN IP4 0.0.0.0 // 会话级连接地址(未指定,媒体级单独配置)
t=0 0 // 永久有效
a=StreamCount:integer;2 // 会话级属性:2个媒体流
m=audio 0 RTP/AVP 96 // 音频流,端口0(待协商),协议RTP/AVP,格式96
b=AS:24 // 音频带宽24kbit/s
a=control:streamid=1 // 媒体级属性:指定流ID为1
a=rtpmap:96 MPEG4-GENERIC/32000/2 // 格式96对应AAC,采样率32000Hz,2声道
m=video 0 RTP/AVP 97 // 视频流,端口0,协议RTP/AVP,格式97
a=control:streamid=2 // 流ID为2
a=rtpmap:97 MP4V-ES/2500 // 格式97对应MPEG-4视频,时钟速率2500Hz
- 关键逻辑:
- 通过
a=StreamCount
声明多流; - 每个媒体流通过
m=
定义基础参数,a=control
区分流ID,a=rtpmap
补充编码细节。
- 通过
示例2:WebRTC中的SDP(连接协商场景)
v=0
o=- 7595655801978680453 2 IN IP4 112.90.139.105 // 会话源(IP地址可忽略,由ICE协商实际地址)
s=- // 会话名称为空
t=0 0 // 永久有效
a=group:BUNDLE 0 1 // 会话级属性:音频(0)和视频(1)复用同一传输通道
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 // 音频流,端口9(虚拟端口),加密RTP协议,支持Opus(111)等编码
a=rtpmap:111 opus/48000/2 // Opus编码,采样率48000Hz,2声道
m=video 9 UDP/TLS/RTP/SAVPF 122 // 视频流,支持H264(122)
a=rtpmap:122 H264/90000 // H264编码,时钟速率90000Hz
- 关键逻辑:
- 通过
a=group:BUNDLE
实现音视频流复用,减少端口占用; a=rtpmap
明确动态负载类型的编码参数,适应WebRTC的灵活协商需求。
- 通过
3.3 重点知识
1. 基础概念类
- 问题1:SDP的主要作用是什么?与RTSP的关系?
回答:SDP用于描述媒体会话参数(如编码格式、传输地址),RTSP用于控制会话流程(如PLAY、SETUP)。RTSP通过ANNOUNCE/DESCRIBE方法传递SDP,实现媒体协商。 - 问题2:SDP的必需字段有哪些?
回答:必需字段包括v=
(版本)、o=
(会话源)、s=
(会话名)、t=
(时间)、m=
(媒体描述)。
2. 字段与协议流程类
- 问题1:m=字段的作用是什么?常见子字段有哪些?
回答:m=
定义媒体流的核心参数,包括媒体类型、端口、传输协议、格式列表。例如m=video 45678 RTP/AVP 96
表示视频流,端口45678,RTP协议,格式96。 - 问题2:a=rtpmap的作用是什么?何时需要?
回答:a=rtpmap
用于描述动态RTP负载类型的编码细节(如H264的时钟速率)。当媒体格式为动态类型(非标准静态类型,如G.711)时必须添加,例如:m=video 0 RTP/AVP 96 // 动态格式96 a=rtpmap:96 H264/90000 // 补充编码参数 ```。
3. 应用场景类
- 问题1:多流场景下如何区分不同媒体流?
回答:通过m=
字段分别定义每个媒体流,并使用a=control
或streamid
属性标识流ID。例如:m=audio 0 RTP/AVP 96 // 音频流,streamid=1 a=control:streamid=1 m=video 0 RTP/AVP 97 // 视频流,streamid=2 a=control:streamid=2 ```。
- 问题2:WebRTC中SDP的核心作用是什么?
回答:WebRTC通过SDP交换音视频编解码器(如Opus、H264)、网络候选地址(ICE协商)、传输协议(如SRTP加密)等信息,实现端到端连接的建立。
4 RTCP
4.1 RTCP基础概念
1. 协议定位与核心功能
- 定义:RTCP(Real-Time Transport Control Protocol,实时传输控制协议)是RTP的配套协议,用于监控RTP传输质量、同步媒体流时间轴,并提供参与者标识等控制信息。
- 与RTP的协作:
- RTP负责传输音视频数据(如H264、AAC),使用偶数UDP端口;
- RTCP负责发送控制报文,使用相邻奇数端口(如RTP端口为8888,则RTCP端口为8889)。
- 核心功能:
- 质量反馈:通过接收方报告(RR)统计丢包率、抖动等网络指标;
- 时间同步:利用发送方报告(SR)中的NTP/RTP时间戳对,对齐不同媒体流的时间轴;
- 参与者标识:通过源描述报告(SDES)中的CNAME唯一标识会话参与者。
2. 报文类型与格式
RTCP定义了5种报文类型,均基于统一的头部格式(4字节固定头):
类型 | PT值 | 功能描述 | 典型场景 |
---|---|---|---|
发送方报告(SR) | 200 | 发送方发送媒体数据的时间、流量等信息 | 推流端周期性发送,用于接收端同步 |
接收方报告(RR) | 201 | 接收方反馈网络质量(丢包、抖动等) | 拉流端定期反馈传输状态 |
源描述(SDES) | 202 | 提供参与者元数据(如CNAME、用户名) | 会话初始化时协商标识 |
离开会话(BYE) | 203 | 通知其他参与者退出会话 | 客户端断开连接时发送 |
应用定义(APP) | 204 | 自定义扩展功能 | 试验性协议扩展 |
关键字段解析:
- SSRC:同步源标识符,必须与对应RTP流的SSRC一致;
- NTP timestamp:64位网络时间协议时间戳,用于绝对时间同步(从1900年1月1日起计);
- RTP timestamp:与RTP数据包时间戳同单位(如90kHz时钟),用于相对时间对齐;
- Length:报文长度(以4字节为单位),需确保总长度为4字节对齐。
二、RTCP核心机制
1. 时间同步:NTP与RTP时间戳的映射
- 问题背景:
不同媒体流(如音频、视频)使用独立的RTP时间戳(如音频48kHz、视频90kHz),需通过绝对时间轴(NTP)实现同步。 - 关键原理:
- SR报文中的时间戳对:每个SR报文包含
<NTP, RTP>
时间戳对,表示“当前RTP时间戳对应NTP绝对时间”。 - 同步公式:
假设音频流时间轴为基准,视频流需通过以下步骤对齐:- 提取音频SR的
(Tan, Tar)
和视频SR的(Tvn, Tvr)
; - 计算时间差:
D = ( T a r − T v r ) − ( T a n − T v n ) D = (Tar - Tvr) - (Tan - Tvn) D=(Tar−Tvr)−(Tan−Tvn) - 调整视频时间戳:
Tvr' = Tvr + D
。
- 提取音频SR的
- SR报文中的时间戳对:每个SR报文包含
- 代码实现:
在FFmpeg中,RTP时间戳基于base_timestamp
生成,RTCP的SR时间戳通过ntp_time - first_rtcp_ntp_time + base_timestamp
计算。
2. 传输控制:发送间隔与流量调节
- 发送策略:
- 周期性发送:默认每5秒发送一次RTCP报文,确保时间同步时效性;
- 流量控制:RTCP流量不超过RTP流量的5%,通过公式动态调整:
[
rtcp_bytes = (octet_count - last_octet_count) \times 0.5%
]
(octet_count
为RTP发送字节数)。
- 特殊场景:
- 推流时,RTCP包需发送至服务器,用于服务器监控传输质量;
- 拉流时,客户端通过RTCP RR反馈网络状态,服务器据此调整码率。
4.2 重点
1. 基础概念类
- 问题1:RTCP与RTP的区别?
回答:- RTP是数据传输协议,负责承载音视频数据(如H264包),使用偶数端口;
- RTCP是控制协议,负责质量反馈、时间同步和参与者标识,使用相邻奇数端口,流量占比≤5%。
- 问题2:SR报文的作用是什么?关键字段有哪些?
回答:- 作用:提供发送方的时间戳(NTP/RTP)、发送包数、字节数,用于接收端同步媒体流;
- 关键字段:
SSRC
:必须与对应RTP流一致,标识数据源;NTP timestamp
:绝对时间,用于跨流同步;RTP timestamp
:相对时间,用于计算媒体帧间隔。
2. 时间同步类
- 问题1:如何实现音视频同步?RTCP的作用是什么?
回答:- 原理:通过RTCP SR报文中的
<NTP, RTP>
时间戳对,将音频和视频的时间轴映射到NTP绝对时间轴; - 步骤:
- 音频和视频流各自发送SR报文,包含当前时间戳对;
- 接收端根据时间戳对计算偏差
D
,调整视频帧播放时间。
- 原理:通过RTCP SR报文中的
- 问题2:NTP与RTP时间戳的区别?
回答:- NTP是绝对时间(从1900年起计),单位为秒+皮秒,用于跨设备同步;
- RTP是相对时间,单位为采样率(如90kHz表示每帧间隔1/90000秒),用于媒体内时序控制。
3. 应用场景类
- 问题1:推流和拉流时,RTCP的流向有何不同?
回答:- 推流(Client→Server):RTCP由客户端发送至服务器,服务器通过SR/RR监控传输质量;
- 拉流(Server→Client):RTCP由服务器发送至客户端,客户端通过RR反馈丢包、抖动等信息。
- 问题2:能否不发送RTCP实现音视频同步?
回答:- 理论上可行,需满足:
- 音视频流的
base_timestamp
初始化一致; - 采样率已知且固定(如音频48kHz、视频90kHz);
- 音视频流的
- 实际中RTCP是标准方案,可动态校准时钟偏差。
- 理论上可行,需满足:
4. 报文解析类
- 问题:根据以下SR报文片段,解析关键信息
解析:Sender SSRC: 0xD801E570 NTP MSW/LSW: 0xE34CC9FB / 0xEF1A9FBE RTP timestamp: 2794561330 Packet count: 0 Octet count: 0
- SSRC对应视频流(0xD801E570),发送方尚未发送数据(packet count=0);
- NTP时间转换为Unix时间:
(MSW - 2208988800) + LSW/1e12
,表示报告发送时刻; - RTP时间戳
2794561330
对应实际播放时间:2794561330 / 90000 ≈ 31050.68秒
。
5 总结
RTSP、RTP、SDP、RTCP 是音视频流媒体传输的核心协议,分别负责会话控制、媒体数据传输、会话描述和传输控制。它们通过分层协作实现实时流的建立、传输与同步,以下是具体工作流程及协作机制:
一、协议分工与核心作用
协议 | 层次 | 核心功能 | 典型交互场景 |
---|---|---|---|
RTSP | 应用层 | 会话控制(建立/暂停/关闭流),传输协议协商 | OPTION查询方法、SETUP建立传输通道 |
SDP | 应用层 | 描述会话媒体参数(编码格式、端口、时间轴) | 通过RTSP的DESCRIBE/ANNOUNCE传递 |
RTP | 传输层 | 实时媒体数据封装与传输(音视频分片) | 携带H264/AAC数据,通过UDP发送 |
RTCP | 传输层 | 传输质量监控、时间同步、参与者标识 | 发送SR/RR报文反馈丢包率、同步NTP时间戳 |
二、协同工作流程(以拉流为例)
1. 会话建立与媒体协商(RTSP + SDP)
- OPTION阶段(RTSP)
- 客户端发送
OPTION
请求查询服务器支持的方法(如DESCRIBE、SETUP),服务器返回Public
头字段(含可用方法列表)。
- 客户端发送
- DESCRIBE阶段(RTSP + SDP)
- 客户端发送
DESCRIBE
请求获取媒体描述,服务器返回包含SDP数据的响应,内容包括:- 媒体类型(音频/视频)、编码格式(H264/AAC);
- 传输协议(RTP/AVP)、端口范围(如客户端RTP端口21988-21989);
- 时间信息(t=0 0表示永久有效)。
- 客户端发送
- SETUP阶段(RTSP + RTP/RTCP端口协商)
- 客户端发送
SETUP
请求,通过Transport
头字段指定RTP/RTCP端口(如client_port=21988-21989
),服务器响应确认并分配服务器端口(如server_port=39188-39189
)。 - 关键成果:确定RTP通道(偶数端口)和RTCP通道(奇数端口),建立会话关联。
- 客户端发送
2. 媒体传输与控制(RTP + RTCP + RTSP)
- PLAY阶段(RTSP触发数据传输)
- 客户端发送
PLAY
请求启动流,服务器通过RTP发送媒体数据,每个RTP包包含:- 时间戳(Timestamp):基于媒体采样率(如视频90kHz),用于解码顺序控制;
- 序列号(Sequence Number):用于检测丢包和重组。
- 客户端发送
- RTCP实时监控(质量反馈与时间同步)
- 发送方报告(SR):服务器周期性发送SR报文,包含:
NTP timestamp
:绝对时间(如Nov 4, 2020 06:34:35 UTC
),用于音视频同步;RTP timestamp
:相对时间(如2794561330
),对应媒体流的采样时间。
- 接收方报告(RR):客户端反馈网络状态,包含:
- 丢包率(Loss fraction=141/256表示约55%丢包);
- 抖动值(Interarrival jitter),用于调整缓冲区。
- 发送方报告(SR):服务器周期性发送SR报文,包含:
- 实时控制(RTSP命令)
- 客户端可发送
PAUSE
/TEARDOWN
命令暂停或关闭流,服务器通过RTSP响应确认。
- 客户端可发送
3. 音视频同步机制(SDP + RTP + RTCP)
- SDP的时间基定义:在SDP中通过
a=rtpmap
指定编码的时钟速率(如90000 Hz
对应视频,48000 Hz
对应音频)。 - RTCP的时间轴映射:
- 服务器在SR报文中发送
<NTP, RTP>
时间戳对(如NTP=2023-10-01 12:00:00 UTC
,RTP=2794561330
); - 客户端根据公式计算媒体时间:
[
媒体时间(s) = \frac{RTP时间戳}{时钟速率} = \frac{2794561330}{90000} \approx 31050.68s
] - 跨流同步:通过NTP时间对齐音频和视频的RTP时间戳,消除采样率差异。
- 服务器在SR报文中发送
4. 推流场景的差异(ANNOUNCE替代DESCRIBE)
- OPTION阶段:与拉流一致,查询服务器方法。
- ANNOUNCE阶段:客户端发送包含SDP的
ANNOUNCE
请求,告知服务器媒体描述(如推流的视频编码、端口)。 - RECORD阶段:客户端发送
RECORD
请求开始推流,服务器通过RTP接收数据,RTCP反馈接收质量。
总结:协议协作的核心逻辑
- RTSP驱动流程:通过方法调用(DESCRIBE/SETUP/PLAY)控制会话生命周期。
- SDP定义内容:明确“传什么”(媒体类型、编码)和“如何传”(协议、端口)。
- RTP搬运数据:将媒体流分片为UDP包,实时传输。
- RTCP保驾护航:监控“传得如何”(质量反馈)和“时序是否正确”(时间同步)。