SRS流媒体服务器实战:从零搭建到多协议直播推流(含OBS+FFmpeg配置)
SRS流媒体服务器实战:从零搭建到多协议直播推流(含OBS+FFmpeg配置)
最近在帮一个在线教育团队搭建内部直播系统时,我再次用到了SRS。说实话,第一次接触SRS还是几年前,当时为了一个紧急的直播项目,需要在两天内搭建起一套能支持上千人同时在线的流媒体服务。试了好几个方案,要么配置复杂得让人头疼,要么性能达不到要求,最后在GitHub上发现了SRS,用下来发现这确实是个“宝藏”项目——配置简单、性能稳定,关键是协议支持全面。现在每次遇到需要快速搭建直播服务的场景,我第一个想到的就是它。
如果你正在寻找一个既能快速上手,又能满足生产环境要求的流媒体服务器,SRS绝对值得你花时间研究。这篇文章不会只给你一堆命令和配置文件,我会结合自己踩过的坑,从环境选择、协议对比、实战配置到性能调优,一步步带你搭建一个真正能用的SRS直播系统。无论你是想搭建个人直播间,还是为企业部署一套稳定的直播服务,这里面的经验都能帮你少走弯路。
1. 环境准备与SRS安装:选对系统,事半功倍
选择什么样的操作系统来部署SRS,直接影响到后续的维护成本和系统稳定性。我个人的经验是,Ubuntu LTS版本是最省心的选择,特别是对于新手。它的包管理器完善,社区支持好,遇到问题容易找到解决方案。CentOS/RHEL系列当然也可以用,但如果你对Linux系统管理不太熟悉,可能会在一些依赖库的安装上多花些时间。
注意:无论选择哪个系统,都建议使用最新的LTS版本。旧版本的系统虽然稳定,但可能会缺少一些新特性支持,或者需要手动编译较新版本的依赖库,徒增复杂度。
在开始安装之前,确保系统已经更新到最新状态。这个步骤看似简单,却能避免很多因版本不一致导致的奇怪问题。
# Ubuntu/Debian系统
sudo apt update && sudo apt upgrade -y
# CentOS/RHEL系统
sudo yum update -y
接下来安装编译SRS所需的基础工具链。这里有个小技巧:如果你打算在生产环境使用,建议一次性把可能用到的开发工具都装上,避免后续需要某个功能时又要重新编译。
# Ubuntu/Debian
sudo apt install -y git build-essential automake libtool pkg-config
# CentOS/RHEL
sudo yum groupinstall "Development Tools" -y
sudo yum install -y git autoconf automake libtool
SRS提供了三种安装方式,每种适合不同的使用场景:
| 安装方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 源码编译 | 需要自定义功能、深度定制 | 灵活性最高,可启用所有模块 | 编译耗时,依赖解决稍复杂 |
| Docker容器 | 快速测试、隔离环境 | 秒级部署,环境干净 | 性能略有损耗,网络配置需注意 |
| 预编译包 | 生产环境快速部署 | 安装简单,官方优化 | 版本可能不是最新 |
对于大多数用户,我推荐从源码编译安装。虽然多花几分钟编译时间,但你能获得最完整的特性支持,而且后续的配置调整也更有灵活性。编译过程其实很简单:
git clone https://github.com/ossrs/srs.git
cd srs/trunk
# 这里我习惯启用所有常用模块
./configure --prefix=/usr/local/srs \
--with-http-api \
--with-http-server \
--with-ffmpeg \
--with-transcode \
--with-ingest \
--with-ssl \
--with-hls
make -j$(nproc) # 使用所有CPU核心加速编译
sudo make install
编译完成后,SRS的可执行文件会安装在/usr/local/srs目录下。我建议创建一个systemd服务文件,这样服务器重启后SRS能自动启动,管理起来也更方便。
sudo tee /etc/systemd/system/srs.service << 'EOF'
[Unit]
Description=SRS Streaming Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/srs/objs/srs -c /usr/local/srs/conf/srs.conf
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -QUIT $MAINPID
Restart=always
User=root
WorkingDirectory=/usr/local/srs
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable srs
2. 核心配置详解:从基础到生产级优化
SRS的配置文件srs.conf是它的“大脑”,理解每个配置项的含义,能让你在遇到问题时快速定位。先来看一个我经过多次实践优化后的基础配置模板:
listen 1935;
max_connections 1000;
daemon on;
srs_log_tank file;
srs_log_file /var/log/srs.log;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
http_api {
enabled on;
listen 1985;
}
vhost __defaultVhost__ {
# HLS配置
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 5; # 分片时长,影响延迟
hls_window 60; # 播放列表保留时长
hls_cleanup on; # 自动清理旧文件
hls_dispose 0; # 分片删除延迟
}
# HTTP-FLV配置
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
# DVR录制配置
dvr {
enabled on;
dvr_path /data/rec/[app]/[stream].[timestamp].mp4;
dvr_plan session; # 按会话录制
}
}
这个配置启用了SRS最常用的几个功能:RTMP监听(1935端口)、HTTP服务(8080端口)、管理API(1985端口),以及HLS和HTTP-FLV输出。其中几个关键参数需要特别注意:
- hls_fragment:这个值直接影响HLS的延迟。默认10秒意味着观众至少会有10秒的延迟。对于需要较低延迟的场景,可以设置为3-5秒,但要注意太小的值会增加服务器负载。
- max_connections:最大连接数限制。根据服务器配置调整,普通4核8G的服务器设置1000-2000比较合理。
- dvr_path:录制文件的存储路径。确保这个目录有足够的磁盘空间,并且SRS进程有写入权限。
防火墙配置是很多新手容易忽略的一步。SRS需要开放以下端口:
# 如果使用ufw(Ubuntu)
sudo ufw allow 1935/tcp # RTMP
sudo ufw allow 8080/tcp # HTTP/HTTP-FLV/HLS
sudo ufw allow 1985/tcp # API管理
sudo ufw allow 8000/udp # WebRTC(如果启用)
# 如果使用firewalld(CentOS)
sudo firewall-cmd --permanent --add-port=1935/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=1985/tcp
sudo firewall-cmd --reload
在实际项目中,我遇到过好几次因为防火墙没配置好,导致外网无法推流播放的情况。一个快速测试的方法是,在服务器本地用telnet命令检查端口是否真的开放了:
telnet localhost 1935
如果连接成功,说明端口监听正常。然后再从外部网络测试,就能快速定位是防火墙问题还是网络问题。
3. 协议选择与实战推流:RTMP、HLS、HTTP-FLV、WebRTC深度对比
选择什么样的推流和播放协议,直接决定了最终的用户体验。很多开发者一开始只关注功能实现,等用户反馈延迟高、卡顿时才回头来优化协议,这时候往往要改动大量代码。我们先来看看这几种主流协议的对比:
| 协议 | 延迟 | 兼容性 | 适用场景 | 配置复杂度 |
|---|---|---|---|---|
| RTMP | 1-3秒 | 需要Flash或特定播放器 | 传统直播、OBS推流 | 低 |
| HTTP-FLV | 1-3秒 | 需要JavaScript播放器 | 网页直播、移动端 | 中 |
| HLS | 10-30秒 | 原生支持iOS/Android | 点播、高兼容性直播 | 低 |
| WebRTC | <1秒 | 现代浏览器 | 实时互动、视频会议 | 高 |
RTMP虽然因为Flash的没落而风光不再,但它仍然是OBS等专业推流软件的首选协议,配置简单,延迟也相对较低。如果你主要面向桌面端,或者推流端使用OBS,RTMP仍然是个不错的选择。
HTTP-FLV可以看作是RTMP的“升级版”,它使用HTTP协议传输,能穿透大多数防火墙和代理,在网页端通过flv.js等库就能播放。我最近的项目基本都转向了HTTP-FLV,因为它既保持了低延迟,又解决了RTMP在移动端的兼容性问题。
HLS最大的优势是兼容性——iOS和Android原生支持,几乎能在所有设备上播放。但它的延迟通常较高,适合对实时性要求不高的场景,比如赛事回放、课程录播等。
WebRTC是真正的“未来之星”,它能实现500毫秒以内的超低延迟,适合在线教育、视频会议等需要实时互动的场景。不过WebRTC的配置相对复杂,需要处理NAT穿透、TURN服务器等问题。
在实际配置中,我建议同时启用多种协议,让客户端根据自身能力选择最合适的。SRS的配置非常灵活:
vhost __defaultVhost__ {
# 启用所有协议
hls {
enabled on;
hls_fragment 5;
hls_window 60;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
# WebRTC配置(需要额外编译支持)
rtc {
enabled on;
rtmp_to_rtc on;
rtc_to_rtmp on;
}
}
推流测试时,我习惯先用FFmpeg做快速验证,因为它的参数灵活,能模拟各种推流场景:
# 测试视频文件推流
ffmpeg -re -i input.mp4 -c:v copy -c:a copy -f flv rtmp://localhost/live/test
# 摄像头实时推流(Linux)
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset ultrafast -f flv rtmp://localhost/live/camera
# 屏幕捕获推流
ffmpeg -f x11grab -s 1920x1080 -i :0.0 -c:v libx264 -f flv rtmp://localhost/live/screen
# 生成测试信号推流(无实际输入源时)
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 -c:v libx264 -f flv rtmp://localhost/live/testpattern
对于大多数用户来说,OBS Studio是更友好的推流工具。在OBS中配置SRS推流只需要几步:
- 打开OBS设置,进入“推流”选项卡
- 服务类型选择“自定义”
- 服务器地址填写:
rtmp://你的服务器IP/live - 串流密钥可以任意填写,比如
obs_demo - 点击“确定”后,在主界面点击“开始推流”
这里有个细节需要注意:OBS默认的编码参数可能不适合你的服务器配置。如果推流后播放卡顿,可以尝试降低视频码率(比如从6000Kbps降到2000Kbps),或者使用更快的编码预设(如“veryfast”代替“medium”)。
4. 生产环境部署与性能调优
当你的直播服务从测试环境走向生产环境时,有几个关键点需要特别注意。我根据实际运维经验,总结了一套SRS生产环境的最佳实践。
安全配置是首要考虑的问题。默认配置下,任何人都可以向你的SRS服务器推流,这显然是不安全的。SRS提供了基于IP的简单鉴权机制:
vhost security_vhost {
# 推流鉴权:只允许特定IP推流
security {
enabled on;
allow publish 192.168.1.100; # 允许的推流IP
deny publish all; # 拒绝其他所有IP
allow play all; # 允许所有客户端播放
}
}
对于更复杂的鉴权需求,比如基于Token的动态鉴权,可以通过SRS的HTTP回调功能实现。当有客户端推流或播放时,SRS会向预设的HTTP接口发送请求,由你的业务服务器决定是否允许。
性能监控方面,SRS内置的HTTP API提供了丰富的状态信息。我通常会在服务器上部署一个简单的监控脚本:
#!/bin/bash
# 实时监控SRS状态
while true; do
clear
echo "====== SRS状态监控 ======"
echo "时间: $(date)"
echo ""
# 获取服务器摘要信息
curl -s http://localhost:1985/api/v1/summaries | jq '.'
# 获取当前活跃流
echo ""
echo "当前活跃流:"
curl -s http://localhost:1985/api/v1/streams | jq '.streams[] | {app, stream, clients}'
# 系统资源监控
echo ""
echo "系统资源:"
top -bn1 | grep "Cpu\|Mem"
sleep 5
done
这个脚本每5秒刷新一次,显示SRS的推流数、客户端连接数以及系统资源使用情况。当并发量上升时,你可以快速发现瓶颈所在。
性能调优需要根据实际负载情况调整。以下是一些经过验证的优化参数:
# 网络优化
sndbuf 10485760; # 发送缓冲区大小
rcvbuf 10485760; # 接收缓冲区大小
tcp_nodelay on; # 禁用Nagle算法,减少延迟
# 工作进程优化
worker_processes 4; # 根据CPU核心数调整
# HLS优化(平衡延迟和性能)
hls {
hls_fragment 3; # 更小的分片,降低延迟
hls_window 30; # 更短的播放列表
hls_cleanup on;
hls_dispose 0;
hls_m3u8_interval 2; # m3u8更新间隔
hls_ts_file [app]/[stream]-[seq].ts;
}
# 连接限制(防止资源耗尽)
max_connections 2000;
如果单台服务器无法满足需求,SRS支持集群部署。常见的架构是“源站-边缘”模式:一台源站服务器接收所有推流,然后分发给多台边缘服务器,由边缘服务器服务播放请求。
# 边缘服务器配置
origin_cluster on;
vhost __defaultVhost__ {
cluster {
mode remote;
origin 192.168.1.100:1935; # 源站服务器地址
}
}
在实际部署中,我建议至少使用2台边缘服务器做负载均衡。可以使用Nginx作为反向代理,将播放请求分发到不同的边缘服务器:
# Nginx负载均衡配置
upstream srs_servers {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080;
}
server {
listen 80;
location / {
proxy_pass http://srs_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
日志管理也是生产环境不可忽视的一环。SRS默认将日志输出到文件,但长时间运行后日志文件会变得很大。我习惯用logrotate做日志轮转:
sudo tee /etc/logrotate.d/srs << 'EOF'
/var/log/srs.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 root root
postrotate
/usr/bin/killall -HUP srs 2> /dev/null || true
endscript
}
EOF
这个配置会让SRS日志每天轮转一次,保留30天的压缩日志。当磁盘空间紧张时,你可以快速清理旧的日志文件。
最后,关于故障排查,我总结了一个快速检查清单:
- 推流失败:检查防火墙、端口是否开放;检查SRS进程是否运行;查看SRS日志
tail -f /var/log/srs.log - 播放卡顿:检查服务器带宽是否充足;降低推流码率;调整播放器缓冲区大小
- 高延迟:启用低延迟配置;考虑使用HTTP-FLV或WebRTC替代HLS;检查网络路由
- CPU使用率高:检查是否启用了转码;降低视频分辨率;使用硬件加速编码
有一次我遇到一个奇怪的问题:推流正常,但播放时断时续。最后发现是服务器的TCP连接数达到了上限。通过调整max_connections和系统级的ulimit设置解决了问题。所以当遇到异常时,不要只盯着SRS本身的配置,系统层面的限制也要考虑进去。
SRS的社区相当活跃,遇到问题时可以在GitHub上搜索相关issue,很可能已经有人遇到过类似问题并给出了解决方案。对于企业级应用,如果担心自己维护的稳定性,也可以考虑购买商业支持服务。不过从我个人的使用经验来看,SRS的稳定性已经足够好,只要配置得当,连续运行几个月不出问题是常态。
更多推荐

所有评论(0)