28、SRS流媒体服务器搭建:SRS部署、RTMP拉流测试、HLS配置、WebRTC转码
这一章,我们来聊聊SRS流媒体服务器。说实话,在流媒体这个领域,SRS算是我个人非常偏爱的一个开源项目。它轻量、高效,而且对国人开发者特别友好——文档是中文的,社区也很活跃。我在好几个项目里都用它来做直播中转和录制服务,从来没掉过链子。
你可能会问:为什么不用Nginx-RTMP或者其他的方案?嗯,Nginx-RTMP虽然经典,但功能相对单一。SRS支持RTMP、HLS、WebRTC、SRT等多种协议,而且配置起来非常直观。说白了,它就是为流媒体而生的,不是那种“顺便支持一下”的半吊子方案。
本章核心目标:从零搭建一台SRS服务器,完成RTMP推拉流测试,配置HLS切片,最后打通WebRTC转码链路。整个过程我会带着你一步步走,顺便分享一些我在生产环境中踩过的坑。
SRS部署:两种方式,我推荐Docker
SRS的部署方式主要有两种:源码编译和Docker容器。我个人习惯用Docker,原因很简单——省心。你不需要操心依赖库的版本冲突,也不用管编译过程中那些莫名其妙的报错。
先看Docker方式,这是我最常用的:
# 拉取SRS镜像
docker pull ossrs/srs:5
# 运行容器,映射端口
docker run -d --name srs \
-p 1935:1935 \
-p 8080:8080 \
-p 1985:1985 \
-p 8000:8000/udp \
ossrs/srs:5
这里解释一下端口的作用:1935是RTMP的默认端口,8080是HTTP API和HLS的访问端口,1985是WebRTC的信令端口,8000/udp则是WebRTC的媒体端口。我在项目中遇到过一个问题——忘记开放UDP端口,结果WebRTC一直连不上,排查了半天才发现是防火墙的问题。嗯,这个坑你记住就好。
如果你坚持要源码编译,也没问题:
git clone -b 5.0release https://github.com/ossrs/srs.git
cd srs/trunk
./configure
make
./objs/srs -c conf/srs.conf
编译时间取决于你的机器性能,一般5到10分钟。我第一次编译的时候,make阶段报了个错,原因是系统缺少libssl-dev。装上就好了:apt install libssl-dev。
小提示:生产环境建议使用Docker部署,方便版本管理和回滚。开发环境可以用源码编译,方便调试和修改配置。
RTMP拉流测试:验证服务器是否跑起来了
服务器启动后,第一件事就是验证它能不能正常工作。RTMP是最基础的协议,也是SRS的看家本领。
我们先推流。你可以用FFmpeg或者OBS。这里我用FFmpeg演示:
# 推流一个测试视频
ffmpeg -re -i test.mp4 \
-c copy -f flv \
rtmp://192.168.1.100/live/stream1
推流成功后,用VLC或者FFplay拉流验证:
ffplay rtmp://192.168.1.100/live/stream1
如果画面正常显示,说明RTMP链路通了。我记得有一次,推流端显示成功,但拉流端就是黑屏。后来发现是防火墙把1935端口拦了。你想想看,推流和拉流其实是两个方向,防火墙规则要双向放行才行。
注意:RTMP默认使用TCP 1935端口。如果你的服务器有防火墙,记得放行这个端口。另外,推流地址中的live是应用名,stream1是流名,你可以自定义。
HLS配置:让直播支持苹果生态
RTMP虽然好,但苹果设备不支持它。HLS(HTTP Live Streaming)是苹果推出的协议,兼容性极好。SRS对HLS的支持非常成熟,配置起来也很简单。
打开SRS的配置文件conf/srs.conf,找到HLS相关的配置段:
vhost __defaultVhost__ {
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 10;
hls_window 60;
}
}
参数说明:
hls_fragment:每个TS片段的时长,单位秒。我一般设10秒,兼顾延迟和兼容性。hls_window:保留的窗口时长,单位秒。超过这个时间的片段会被删除。hls_path:HLS文件的输出目录。注意要有写入权限。
配置完成后,重启SRS:
docker restart srs
然后推流,HLS就会自动生成。访问地址是:
http://192.168.1.100:8080/live/stream1.m3u8
用浏览器或者VLC打开这个地址,就能看到HLS直播了。我在项目中遇到过一个问题——HLS文件生成了,但播放器一直缓冲。后来发现是hls_fragment设得太长,导致首屏延迟过高。改成5秒后,问题解决了。
经验之谈:HLS的延迟通常在10-30秒之间,这是由切片时长和播放器缓冲策略共同决定的。如果你需要低延迟,可以考虑WebRTC或者SRT协议。
WebRTC转码:从RTMP到WebRTC的桥梁
WebRTC是实时通信的终极方案,延迟可以做到1秒以内。但WebRTC本身不直接支持RTMP推流,需要SRS做转码中转。
SRS 5.0版本开始,内置了WebRTC转码功能。配置方式如下:
vhost __defaultVhost__ {
rtc {
enabled on;
rtmp_to_rtc on;
}
}
这个配置的意思是:开启WebRTC功能,并且允许RTMP流转码为WebRTC流。配置完成后,重启SRS。
推流端还是用FFmpeg推RTMP:
ffmpeg -re -i test.mp4 -c copy -f flv rtmp://192.168.1.100/live/stream1
拉流端用浏览器访问WebRTC地址:
webrtc://192.168.1.100/live/stream1
或者通过SRS提供的WebRTC播放页面:
http://192.168.1.100:8080/players/rtc_player.html
打开页面后,输入流地址,点击播放。如果一切正常,你会看到延迟极低的直播画面。我曾经在一个互动直播项目里用这个方案,主播端用OBS推RTMP,观众端用WebRTC拉流,延迟控制在500ms以内,效果非常棒。
注意:WebRTC需要HTTPS或者localhost环境。如果你用公网IP,必须配置SSL证书。另外,WebRTC的UDP端口(8000)必须开放,否则无法建立连接。
整体架构图
下面这张图展示了SRS在整个流媒体链路中的位置和作用。你可以看到,SRS作为核心中转节点,同时支持RTMP推流、HLS分发和WebRTC实时播放。
避坑指南:我踩过的几个坑
最后,分享几个我在SRS部署和使用中遇到的实际问题,希望能帮你少走弯路。
- 端口冲突:有一次我在一台机器上同时跑了Nginx和SRS,结果8080端口被Nginx占用了。SRS启动失败,日志里报
bind failed。解决方案很简单——改SRS的HTTP端口,或者停掉Nginx。 - HLS文件权限:Docker方式部署时,HLS输出目录的权限容易出问题。我习惯在启动容器时挂载一个宿主机目录:
-v /data/hls:/usr/local/srs/objs/nginx/html,这样文件权限就由宿主机控制了。 - WebRTC无法连接:这个问题最常见。原因通常是UDP端口没开放,或者没有配置SSL。记住,WebRTC必须用HTTPS或者localhost。如果你在公网测试,先配好Nginx反向代理和SSL证书。
- 推流断连:推流一段时间后自动断开,检查一下SRS的日志。我遇到过是因为
max_connections设得太小,导致连接被拒绝。调大这个值就好了。
最后说一句:SRS的日志非常详细,遇到问题先看日志。日志路径在/usr/local/srs/objs/srs.log(源码部署)或者通过docker logs srs查看。大部分问题都能在日志里找到线索。
好了,这一章的内容就到这里。SRS的搭建和配置其实不难,关键是理解它的工作流程和协议转换逻辑。你动手试一遍,遇到问题再回头看这一章,应该就能顺利跑起来了。