RTSP 音视频流服务器示例
源码位置: samples/network/micro-rtsp-c/av_stream 查看源码
功能说明
演示如何使用 micro-rtsp-c 库搭建支持音视频同步传输的 RTSP 流媒体服务器,通过 WiFi 网络实时传输摄像头采集的 JPEG 视频和麦克风采集的音频数据,支持标准 RTSP 客户端接入播放。
本示例实现了完整的音视频 RTSP 服务器功能,包括:
使用 JPEG 硬件编码器实时编码摄像头图像
使用 PCMU (μ-law) 编码压缩音频数据
音视频时间戳同步,确保播放流畅
支持 TCP/UDP 双模式传输
自动处理 JPEG 量化表传输
新特性
硬件 JPEG 编码:使用芯片内置 JPEG 编码器,CPU 占用低,编码速度快
实时音视频流:同时传输摄像头视频和麦克风音频,支持双轨道
音视频同步:使用统一的时间戳基准,确保音画同步
PCMU 音频编码:标准 μ-law 编码,兼容性好,CPU 占用低
灵活的分辨率配置:支持多种摄像头分辨率(320x240 / 640x480)
硬件连接
摄像头接口(DVP):
使用板载 DVP 摄像头接口
支持 YUV422 输出格式
分辨率可配置
麦克风接口(I2S):
使用板载麦克风
采样率:8000 Hz
位宽:16-bit
串口输出:
串口 TX: PA3
波特率:921600
使用场景
本示例适用于以下场景:
视频监控:实时查看摄像头画面,支持网络远程查看
物联网设备:智能门铃、婴儿监护器等需要音视频传输的设备
开发调试:验证摄像头和音频采集功能,调试编码参数
示例步骤
初始化 WiFi 并连接到指定 AP
初始化 JPEG 硬件编码器(YUV422 格式,800x600 分辨率)
初始化音频采集(I2S 麦克风,8000Hz 采样率)
配置音频编码器(PCMU,μ-law 编码)
在 8554 端口启动 RTSP 服务器
等待客户端连接
并行处理:
摄像头线程:采集图像 → JPEG 编码 → 发送视频 RTP 包
音频线程:采集音频 → μ-law 编码 → 发送音频 RTP 包
维持音视频时间戳同步
编译
重要提示:在编译前,请先确认您使用的开发板型号。SDK 目前支持以下开发板:
arcs_evb - ARCS EVB 评估板
arcs_mini - ARCS Mini 开发板
根据您的开发板型号,选择对应的编译命令:
在示例目录下执行编译:
# 使用 arcs_evb 开发板
./build.sh -C -DBOARD=arcs_evb
# 或使用 arcs_mini 开发板
./build.sh -C -DBOARD=arcs_mini
Note
如果在 SDK 根目录执行,需要指定示例路径:
# 使用 arcs_evb 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_evb
# 或使用 arcs_mini 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_mini
Note
确保已安装对应的工具链。
烧录
编译完成后,使用 SDK tools 目录下的 cskburn 工具烧录固件:
./tools/burn/cskburn -s /dev/ttyUSB0 -b 3000000 0x0 build/arcs.bin -C arcs
Note
烧录参数说明:
-s /dev/ttyUSB0:串口设备路径,需要根据实际情况修改 - Linux 系统:通常是/dev/ttyUSB0或/dev/ttyACM0- 可通过ls /dev/tty*命令查看可用串口设备 - 不同开发板或 USB 转串口芯片可能使用不同的设备名-b 3000000:烧录波特率(3Mbps)0x0:烧录起始地址build/arcs.bin:编译生成的固件路径-C arcs:芯片类型
注意事项:
确保开发板已正确连接到电脑
如果无法识别串口设备,请检查 USB 连接线是否正常,或尝试其他 USB 端口
预期输出
串口输出:
[rtsp-test] RTSP Server Starting...
[rtsp-test] WiFi connected and IP obtained
[rtsp-test] DHCP Success: IP=192.168.137.166
[camera] Camera initialized: 800x600, YUV422
[camera] JPEG encoder initialized successfully
[audio] Audio initialized: 8000Hz, 16-bit
[audio] PCMU encoder initialized (μ-law)
[rtsp-test] Starting RTSP server on port 8554
+ UDP socket created: rtp_port=6970 rtcp_port=6971
+ Audio UDP transport: rtp_port=6972 rtcp_port=6973
[rtsp-test] client connected: 192.168.137.1
+ RTSP command: DESCRIBE
+ SDP: Video track=track1, Audio track=track2
+ RTSP command: SETUP (track1)
+ Video SETUP: client_port=54224-54225 server_port=6970-6971
+ RTSP command: SETUP (track2)
+ Audio SETUP: client_port=54226-54227 server_port=6972-6973
+ RTSP command: PLAY
+ PLAY: streaming enabled (video+audio)
[camera] Frame captured: 37150 bytes, encoded in 45ms
[audio] Audio frame: 640 bytes -> 320 bytes (μ-law)
+ UDP send VIDEO RTP: size=1082 port=54224 ret=1082
+ UDP send AUDIO RTP: size=332 port=54226 ret=332
客户端播放:
使用 ffplay 播放(UDP 模式,推荐):
ffplay -rtsp_transport udp rtsp://192.168.137.166:8554/mjpeg/1 -fflags nobuffer -flags low_delayffplay
使用 ffplay 播放(TCP 模式):
ffplay -rtsp_transport tcp rtsp://192.168.137.166:8554/mjpeg/1 -fflags nobuffer -flags low_delayffplay
预期效果:
实时显示摄像头画面(约 10-15 fps)
同步播放麦克风采集的音频
核心 API
RTSP 服务器 API
API |
说明 |
|---|---|
|
初始化 RTSP 流媒体服务 |
|
初始化音频配置 |
|
发送视频帧 |
|
发送音频帧 |
JPEG 编码 API
API |
说明 |
|---|---|
|
初始化 JPEG 编码器 |
|
编码一帧图像 |
|
停止编码器 |
音频编码 API
API |
说明 |
|---|---|
|
PCM 16-bit 转 μ-law 编码 |
|
采集并编码音频帧 |
功能详解
音视频同步机制
示例使用统一的时间基准确保音视频同步:
// 视频时间戳(90000 Hz 时钟)
streamer->start_ms = ms; // 记录起始时间
uint32_t elapsed_ms = ms - streamer->start_ms;
streamer->timestamp = elapsed_ms * 90; // 90000/1000 = 90
// 音频时间戳(8000 Hz 采样率)
streamer->audio_timestamp = elapsed_ms * 8; // 8000/1000 = 8
两者使用相同的 start_ms 基准,确保时间轴对齐。
JPEG 编码流程
摄像头采集 YUV422 格式图像
CPU 将 YUYV 交叉格式转换为 JPEG MCU 块格式
DMA 将 MCU 数据传输到 JPEG 编码器
JPEG 硬件编码器输出压缩的 ECS 数据
CPU 构建完整的 JPEG 文件(添加头部、量化表、Huffman 表)
PCMU (μ-law) 音频编码
编码格式:ITU-T G.711 μ-law
采样率:8000 Hz
位宽:16-bit PCM → 8-bit μ-law
帧大小:320 样本(40ms @ 8kHz)
压缩比:2:1(640 字节 → 320 字节)
特点:标准电话音质,CPU 占用极低,兼容性好
关键代码
初始化 JPEG 编码器:
jpeg_enc_cfg_t jpeg_cfg = {
.width = 320,
.height = 240,
.input_format = 0x00 // YUV422
};
jpeg_encoder_init(&jpeg_enc_ctx, &jpeg_cfg);
编码并发送视频帧:
// 采集摄像头图像
camera_capture(yuv_buffer, &yuv_len);
// JPEG 硬件编码
jpeg_encoder_encode(&jpeg_enc_ctx, yuv_buffer, jpeg_buffer, &jpeg_len);
// 发送 RTSP 视频流
rtsp_streamer_stream_frame(&streamer, jpeg_buffer, jpeg_len, current_time_ms);
音频编码并发送:
// 从队列获取 PCM 音频数据并自动编码为 μ-law
uint8_t *audio_frame = NULL;
uint32_t audio_len = 0;
while (audio_capture_frame(&audio_frame, &audio_len) == 0) {
// 发送 RTSP 音频流(已编码为 μ-law)
rtsp_streamer_stream_audio_frame(&streamer, audio_frame, audio_len, current_time_ms);
}
PCM 转 μ-law 编码实现:
static uint8_t pcm16_to_ulaw(int16_t pcm_val)
{
const int16_t CLIP = 32635;
const int16_t BIAS = 0x84;
uint8_t sign = (pcm_val < 0) ? 0x80 : 0;
if (sign) pcm_val = (int16_t)(-pcm_val);
if (pcm_val > CLIP) pcm_val = CLIP;
pcm_val = (int16_t)(pcm_val + BIAS);
int exponent = 7;
for (int exp_mask = 0x4000; (pcm_val & exp_mask) == 0 && exponent > 0;
exp_mask >>= 1, exponent--);
int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
uint8_t ulaw = (uint8_t)(~(sign | (exponent << 4) | mantissa));
return ulaw;
}
配置音视频参数:
// 配置音频编码参数
rtsp_audio_config_t audio_cfg = {
.payload_type = 0, // PCMU 标准负载类型
.sample_rate = 8000, // 8kHz 采样率
.channels = 1, // 单声道
.codec_name = "PCMU"
};
rtsp_streamer_init_audio(&streamer, &audio_cfg);
配置说明
WiFi 配置(main.c):
#define TARGET_WIFI_SSID "Your_SSID"
#define TARGET_WIFI_PWD "Your_Password"
摄像头配置(camera.h):
#define CAMERA_WIDTH 800
#define CAMERA_HEIGHT 600
#define CAMERA_FORMAT YUV422 // YUYV 格式
音频配置(audio.h):
#define AUDIO_SAMPLE_RATE 8000 // 8kHz 采样率
#define AUDIO_FRAME_SIZE 320 // 40ms 帧长(320样本)
#define AUDIO_CHANNELS 1 // 单声道
传输优化参数:
#define MAX_FRAG_SIZE 950 // RTP 包大小(字节)
#define FRAGMENT_DELAY_US 200 // 片段间延迟(微秒)
注意事项
WiFi 配置:需修改 WiFi SSID 和密码为实际网络信息
摄像头分辨率:
支持 320x240、640x480
高分辨率需要更多带宽和编码时间
建议先使用 640x480 测试
JPEG 量化表:
编码器使用自定义高质量量化表(Quality ≈ 85-90)
自动在第一个 RTP 包中传输量化表
确保客户端颜色还原准确
音频编码格式:
PCMU (μ-law) 是标准的电话音质编码
固定 8kHz 采样率,8-bit 编码
CPU 占用极低,兼容性好,所有 RTSP 客户端都支持
网络带宽:
800x600 @ 10fps + PCMU 音频:约 850-1250 Kbps
PCMU 音频固定码率:64 Kbps
确保 WiFi 信号强度足够
UDP 丢包问题:
默认使用 UDP,网络不稳定时可能丢包导致花屏
客户端可切换到 TCP 模式:
ffplay -rtsp_transport tcp rtsp://...已优化片段大小和延迟,减少丢包概率
音视频同步:
示例已实现基于统一时间基准的同步机制
如发现音画不同步,检查帧率设置和网络延迟
内存占用:
JPEG 编码缓冲区:约 100KB
音频缓冲区:约 10KB
每个客户端连接:约 5KB
总计约需 120KB 可用内存
客户端兼容性:
VLC:完全支持,推荐使用
ffplay:完全支持,可选择 TCP/UDP
所有 RTSP 客户端:PCMU 是标准编码,兼容性极好
浏览器:需要插件或转码服务
验证方法
视频质量检查:
观察图像是否清晰,无明显压缩伪影
检查颜色是否准确(不偏色、不过曝)
帧率是否稳定(通过 VLC 统计信息查看)
音频质量检查:
语音是否清晰可辨
有无明显杂音或失真
音量是否合适
同步检查:
拍手或敲击,观察画面与声音是否同步
延迟应小于 200ms
稳定性测试:
长时间运行(1小时以上),检查是否有内存泄漏
频繁连接断开,测试服务器稳定性