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流媒体服务器架构图 推流端 FFmpeg / OBS RTMP SRS 5.0 流媒体服务器 RTMP / HLS / WebRTC HLS HLS切片 .m3u8 / .ts WebRTC WebRTC播放 浏览器 / App RTMP RTMP拉流端 VLC / FFplay SRS同时支持三种输出方式:RTMP、HLS、WebRTC 推流端只需推一路RTMP,SRS自动完成协议转换 端口说明: 1935 (RTMP) | 8080 (HTTP/HLS) | 1985 (WebRTC信令) | 8000/UDP (WebRTC媒体) 配置路径:/etc/srs/srs.conf 或 Docker环境变量

避坑指南:我踩过的几个坑

最后,分享几个我在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的搭建和配置其实不难,关键是理解它的工作流程和协议转换逻辑。你动手试一遍,遇到问题再回头看这一章,应该就能顺利跑起来了。

公众号:蓝海资料掘金营,微信deep3321