4、RTSP服务器搭建:使用Live555搭建RTSP服务器、配置与测试、常见问题排查
好,这一章我们动手搭一个真正的RTSP服务器。我选Live555,原因很简单——它轻量、稳定,而且几乎所有RTSP客户端都能跟它对接。你在网上看到的很多IP摄像头演示,背后跑的就是它。
说白了,Live555就是一个C++写的流媒体服务库。它把RTSP协议、RTP打包、媒体文件解析这些脏活都干了。我们只需要告诉它:媒体文件在哪,端口开多少,剩下的它自己搞定。
核心思路: Live555作为RTSP Server,接收客户端的DESCRIBE/SETUP/PLAY请求,然后通过RTP把H.264或AAC数据推给客户端。WebRTC要跟它融合,第一步就是让Live555先把流发出来。
4.1 编译与安装Live555
我习惯直接从源码编译。别怕,步骤很简单。Live555的源码包在官网就能下,或者用git拉一份。
# 下载源码
wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz
tar -xzf live555-latest.tar.gz
cd live
# 编译
./genMakefiles linux
make -j$(nproc)
# 安装(可选,我一般直接用编译目录)
sudo make install
编译完你会看到几个可执行文件:live555MediaServer、testRTSPClient、testH264VideoStreamer 等等。我们主要用 live555MediaServer 和 testH264VideoStreamer。
我的习惯: 不执行 make install,直接在编译目录里跑。这样换版本方便,删掉目录重新编译就行,不会污染系统。
4.2 快速启动一个RTSP流
Live555自带了一个媒体服务器,你只需要把媒体文件丢进去,它自动就能提供服务。
# 把H.264文件放到当前目录
cp test.264 ./
# 启动服务器
./live555MediaServer
# 默认监听端口 8554
# 访问地址:rtsp://192.168.1.100:8554/test.264
就这么简单。服务器启动后,它会扫描当前目录下的媒体文件,自动创建对应的RTSP URL。客户端连上来,它就开始推流。
但说实话,live555MediaServer 功能有限。它只能播文件,不能处理实时流。如果你需要把摄像头或编码器的实时数据推出去,得用 testH264VideoStreamer 这类程序。
4.3 自定义推流:testH264VideoStreamer
这个程序可以从文件读取H.264数据,然后通过RTSP推出去。它的源码在 testProgs/ 目录下,你可以直接改。
# 用法
./testH264VideoStreamer <H264文件> <端口号>
# 示例:推流 test.264,端口 8554
./testH264VideoStreamer test.264 8554
# 客户端访问
ffplay rtsp://192.168.1.100:8554/h264ESVideoTest
这里有个坑——h264ESVideoTest 是程序里硬编码的流名称。如果你想改,得改源码重新编译。
注意: testH264VideoStreamer 默认只支持H.264裸流(Annex B格式)。如果你的文件是MP4或TS封装,需要先解封装。我遇到过有人拿MP4直接喂进去,结果花屏——因为MP4里的H.264有起始码偏移。
4.4 配置参数详解
Live555的配置主要通过源码里的 config.* 文件。但日常使用,我们更关心运行时参数。
| 参数 | 默认值 | 说明 |
|---|---|---|
| RTSP端口 | 8554 | 主端口,客户端连接用 |
| RTP起始端口 | 5000 | 每个流占用两个端口(RTP+RTCP) |
| RTP端口范围 | 5000-5050 | 最多支持25个并发流 |
| HTTP隧道端口 | 80 | 用于防火墙穿透 |
| 多播TTL | 255 | 多播时有效 |
这些参数在 live555MediaServer 里是写死的。如果你要改,得改 DynamicRTSPServer.cpp 里的端口范围。
4.5 测试与验证
服务器跑起来后,怎么知道它工作正常?我一般用三步验证法。
- telnet 测试: 先看端口通不通
- ffplay 播放: 直接拉流看画面
- Wireshark 抓包: 看RTSP交互是否完整
# 第一步:端口测试
telnet 192.168.1.100 8554
# 如果连接成功,会看到空白界面,按 Ctrl+] 退出
# 第二步:ffplay 播放
ffplay -rtsp_transport tcp rtsp://192.168.1.100:8554/h264ESVideoTest
# 第三步:抓包分析
# 在Wireshark里过滤 rtsp or rtp
# 重点关注 OPTIONS → DESCRIBE → SETUP → PLAY 的交互
如果ffplay能正常出画面,说明服务器没问题。如果卡住或花屏,八成是文件格式或编码参数不对。
我的经验: 用ffplay测试时加 -v debug 参数,能看到详细的SDP信息和RTP包序号。我曾经靠这个发现一个摄像头发的RTP时间戳是乱的——每帧时间戳都一样,导致播放器以为只有一帧。
4.6 常见问题排查
这部分我踩过的坑比较多,列几个典型的。
4.6.1 客户端连不上服务器
最常见的原因:防火墙。Live555默认用UDP端口5000-5050,很多云服务器或公司网络会封这些端口。
# 临时关闭防火墙测试
sudo ufw disable
# 或者开放端口
sudo ufw allow 8554/tcp
sudo ufw allow 5000:5050/udp
如果防火墙没问题,检查服务器是否真的在监听:
netstat -tulpn | grep 8554
4.6.2 播放花屏或绿屏
这个问题我遇到过好几次。原因通常是H.264文件的SPS/PPS信息丢失或不对。
Live555在DESCRIBE回复的SDP里会包含SPS/PPS。如果文件里没有这些信息,客户端就不知道怎么解码。
# 检查文件是否包含SPS/PPS
ffprobe -show_packets test.264 | grep -E "sps|pps"
# 如果没有,手动添加
# 用工具提取SPS/PPS,或者重新编码时加上
我曾经踩过的坑: 有一次从摄像头拿到的H.264流,SPS里把分辨率写成了1920x1080,但实际视频只有1280x720。结果播放器按1920x1080解码,画面拉伸变形。排查了半天才发现是SPS参数不对。
4.6.3 RTP时间戳不同步
如果你推的是音视频混合流,音频和视频的RTP时间戳必须基于同一个时钟。Live555默认用90000Hz作为视频时间戳基准,音频用采样率。如果两个流的时间戳基准不一致,播放器会音画不同步。
解决办法:在 StreamParser.cpp 里统一时间戳基准,或者用 gettimeofday 生成绝对时间戳。
4.6.4 多客户端并发问题
Live555默认支持最多25个并发客户端(因为RTP端口只有25对)。如果你需要更多,得改端口范围。
// 在 DynamicRTSPServer.cpp 里修改
#define RTP_PORT_MIN 5000
#define RTP_PORT_MAX 6000 // 改成1000对端口
但注意,每个客户端会占用一对UDP端口。如果客户端用TCP模式(-rtsp_transport tcp),端口占用会少一些。
4.7 性能调优建议
Live555本身性能不错,但有些场景需要调优。
| 场景 | 建议 |
|---|---|
| 高并发(>50路) | 改用TCP模式,减少UDP端口占用 |
| 低延迟(<200ms) | 减小RTP包大小(默认1400字节),降低缓冲 |
| 跨网传输 | 开启HTTP隧道,绕过防火墙 |
| 多码率适配 | 需要自己实现多码率逻辑,Live555原生不支持 |
嗯,说到多码率,Live555确实不支持。如果你需要自适应码率,得在应用层自己做。我们后面章节会讲怎么用WebRTC的Simulcast来实现类似效果。
总结一下: Live555搭建RTSP服务器不难,难的是把流稳定地推出去。文件格式、SPS/PPS、端口配置、时间戳同步——每个环节都可能出问题。但只要你按我上面说的步骤来,大部分坑都能避开。