嵌入式音视频开发——RTSP协议

嵌入式音视频开发——RTSP协议

一、RTSP协议核心定位

1.1 一句话定义

RTSP(Real-Time Streaming Protocol,实时流协议)是专门用于控制音视频流媒体播放的应用层协议,你可以把它理解为流媒体的"遥控器"——它不负责传输音视频数据本身,只负责发送"播放、暂停、快进、停止"等控制命令,是嵌入式音视频领域(IPC摄像头、NVR、车载监控、无人机图传)最核心的协议之一。

1.2 铁三角分工(必懂)

初学者最容易混淆这三个协议,它们是嵌入式音视频流媒体的标准组合,各司其职:

协议 全称 核心职责 传输方式 默认端口 类比
RTSP 实时流协议 建立/控制媒体会话(播放、暂停、快进、定位、关闭) TCP 554 电影院的遥控器
RTP 实时传输协议 传输实际的音视频数据(H.264/H.265视频、G.711/AAC音频) UDP(优先)/TCP 随机偶数端口 电影放映机的胶片
RTCP RTP控制协议 监控传输质量(丢包率、延迟、抖动)、同步音视频 UDP RTP端口+1 放映员的对讲机

关键结论:RTSP只负责"发号施令",真正的音视频数据走RTP,RTCP负责"质量反馈"。

1.3 RTSP核心特点

  1. 双向控制:客户端可以控制服务器,服务器也可以主动通知客户端(如流断开、异常)
  2. 媒体无关:支持任何格式的音视频流(H.264/H.265、MJPEG、AAC、G.711等)
  3. 传输无关:可以基于UDP、TCP、HTTP等多种传输层协议
  4. 状态保持:服务器会维护每个客户端的会话状态(播放中、暂停中、已停止)
  5. 嵌入式友好:协议轻量,实现简单,适合资源有限的嵌入式设备

1.4 嵌入式领域典型应用场景

  • IPC网络摄像头:几乎所有网络摄像头都支持RTSP协议输出视频流
  • NVR网络硬盘录像机:通过RTSP协议从IPC拉取视频流并存储
  • 车载监控系统:车内摄像头通过RTSP将视频传输到中控屏
  • 无人机图传:无人机通过RTSP将实时画面传输到遥控器
  • 视频会议系统:点对点或多点视频会议的媒体控制

二、RTSP协议完整工作流程

2.1 整体流程概览

RTSP工作流程分为6个标准阶段,所有RTSP设备(海思/瑞芯微IPC、NVR等)都严格遵循:

  1. TCP连接建立(RTSP基于TCP)
  2. OPTIONS:询问服务器支持的命令
  3. DESCRIBE:获取媒体信息(SDP描述文件)
  4. SETUP:建立音视频传输通道
  5. PLAY:开始播放(服务器开始发送RTP数据)
  6. TEARDOWN:结束会话并释放资源

2.2 逐步骤详解(含真实报文)

步骤1:建立TCP连接
  • 客户端主动连接服务器的554/TCP端口
  • 这一步和HTTP连接完全一致,是所有RTSP命令的传输通道
步骤2:OPTIONS(查询能力)

客户端发送

OPTIONS rtsp://192.168.1.100/stream1 RTSP/1.0
CSeq: 1
User-Agent: MyClient

服务器回复

RTSP/1.0 200 OK
CSeq: 1
Public: OPTIONS, DESCRIBE, SETUP, PLAY, TEARDOWN

作用:确认服务器支持哪些RTSP操作,保证后续命令能正常执行。

步骤3:DESCRIBE(获取媒体信息)

客户端发送

DESCRIBE rtsp://192.168.1.100/stream1 RTSP/1.0
CSeq: 2
Accept: application/sdp

服务器回复(SDP描述文件):

v=0
o=- 12345 12345 IN IP4 192.168.1.100
s=RTSP Session
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
m=audio 0 RTP/AVP 8
a=rtpmap:8 PCMA/8000

SDP核心信息

  • 视频编码:H.264,时钟频率90000Hz
  • 音频编码:G.711 a-law,时钟频率8000Hz
  • 负载类型:视频96,音频8

作用:让客户端知道如何解码、如何接收RTP数据。

步骤4:SETUP(建立传输通道,最关键)

需要为每一路媒体(视频、音频)分别发送SETUP命令:

视频通道SETUP

SETUP rtsp://192.168.1.100/stream1/track1 RTSP/1.0
CSeq: 3
Transport: RTP/AVP;unicast;client_port=5000-5001

服务器回复

RTSP/1.0 200 OK
CSeq: 3
Session: 12345678
Transport: RTP/AVP;unicast;client_port=5000-5001;server_port=6000-6001

关键信息

  • 客户端用5000端口接收视频RTP,5001端口接收视频RTCP
  • 服务器分配Session ID: 12345678,后续所有命令必须携带
  • 音频通道同理,trackID通常为track2,端口为5002-5003
步骤5:PLAY(开始播放)

客户端发送

PLAY rtsp://192.168.1.100/stream1 RTSP/1.0
CSeq: 5
Session: 12345678
Range: npt=0.000-

服务器回复

RTSP/1.0 200 OK
CSeq: 5
Session: 12345678
RTP-Info: url=track1;seq=1234;rtptime=5678

重要变化:从这一刻起,服务器不再通过RTSP连接发送数据,而是直接通过UDP向约定的端口发送RTP音视频数据包。

步骤6:播放过程控制(可选)
  • PAUSE:暂停推流
  • PLAY:恢复播放
  • GET_PARAMETER:获取当前播放状态
  • SET_PARAMETER:设置播放参数(如音量)
步骤7:TEARDOWN(结束会话)

客户端发送

TEARDOWN rtsp://192.168.1.100/stream1 RTSP/1.0
CSeq: 6
Session: 12345678

服务器回复:200 OK

  • 服务器停止发送RTP数据
  • 释放Session资源
  • 关闭UDP端口
  • 客户端可关闭TCP连接

2.3 完整流程图

客户端             服务器
  |                  |
  |--- TCP 连接 ----->|
  |                  |
  |--- OPTIONS ------>|
  |<--- 200 OK -------|
  |                  |
  |--- DESCRIBE ----->|
  |<----- SDP --------|
  |                  |
  |--- SETUP 视频 --->|
  |<-- Session ID ----|
  |                  |
  |--- SETUP 音频 --->|
  |<-- Session ID ----|
  |                  |
  |----- PLAY ------->|
  |                  |
  |<==== RTP 流 ======|  视频+音频持续传输
  |                  |
  |--- TEARDOWN ----->|
  |<--- 200 OK -------|
  |                  |
  └── TCP 断开 ───────┘

三、RTSP客户端代码实现

3.1 解析H.264帧的RTSP客户端

代码功能

  1. 完整RTSP标准流程实现
  2. 独立UDP Socket接收RTP数据
  3. 解析RTP头部信息
  4. 支持H.264 RTP两种封装格式(单NALU + FU-A分片重组)
  5. 保存为可直接播放的.h264文件

完整代码(rtsp_h264_client.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define RTSP_PORT 554
#define RTP_CLIENT_PORT 5000
#define BUFFER_SIZE 1024 * 64
#define CSEQ_START 1

// 全局变量
int rtsp_sock;                  // RTSP TCP Socket
int rtp_sock;                   // RTP UDP Socket
int cseq = CSEQ_START;
char session_id[64] = {
   
   0};
char buffer[BUFFER_SIZE];
FILE *h264_file;                // 输出的.h264文件

// H.264相关状态
int fu_started = 0;             // FU-A分片是否开始
unsigned char fu_nalu_type = 0; // FU-A重组后的NALU类型

// 1. TCP连接RTSP服务器
int rtsp_connect(const char *ip) {
   
   
    struct
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值