RTMP到WebRTC低延迟直播测试环境搭建指南
RTMP 到 WebRTC 的测试环境,是很多低延迟直播项目的第一步。这次我们来拆解一套可以直接落地的方案:用开源流媒体服务器接收 RTMP 推流,再通过 WebRTC 让浏览器无插件拉流播放,整个过程只需要一台 Linux 测试机,不需要额外 GPU,配置起来也不算复杂。
最核心的 3 个特点是:一是协议转换在服务端完成,推流端继续用 OBS 或 ffmpeg,不需要改客户端;二是浏览器播放端直接使用 WebRTC,免插件、延迟低,非常适合互动直播、摄像头监控、大屏展示这类场景;三是整套环境支持 Docker 启动,可以快速在测试环境里验证,后续也能接 HTTP API 做流管理和自动化测试。这篇文章会带你完成环境准备、服务启动、RTMP 推流、WebRTC 拉流、接口测试、性能观察和常见问题排查,最终跑通一个可复用的 rtmp2webrtc 测试环境。
如果你正好要评估低延迟直播方案,或者需要在测试环境里验证 RTMP 转 WebRTC 的延迟和稳定性,这篇文章可以直接收藏。
1. rtmp2webrtc 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | 流媒体协议转换测试环境(RTMP ingest 到 WebRTC playback) |
| 参考实现 | SRS / MediaMTX 等开源流媒体服务器,以下以 SRS 为例 |
| 主要功能 | 接收 RTMP 推流,输出 WebRTC 流,支持 HTTP API 查询流状态 |
| 推荐硬件 | 普通 2 核 4G 以上服务器或虚拟机,不需要独立显卡 |
| 显存占用 | 不涉及 GPU 显存,主要关注 CPU、内存、网络带宽 |
| 支持平台 | Linux 主机或 Docker,Windows/macOS 可作为推流端和播放端 |
| 启动方式 | Docker 启动 / 二进制启动 / systemd 托管 |
| 是否支持 API | 支持 HTTP API,可用于查询流列表、客户端列表、踢流等 |
| 是否支持批量任务 | 支持多路 RTMP 流同时输入,适合做多流并发测试 |
| 适合场景 | 低延迟直播测试、WebRTC 播放验证、内部监控平台、设备视频接入验证 |
这张表明确了测试环境的边界:不关注 AI 模型和显存,重点在协议链路、网络连通性和服务稳定性。实际使用中,CPU 和带宽才是主要资源瓶颈。
2. 适用场景与使用边界
2.1 适合谁
这个测试环境适合三类人:
第一类是后端开发或流媒体运维,需要评估 WebRTC 播放效果,但又不想自己从零写协议栈。第二类是前端开发者,需要用一个可靠的 RTMP 推流源来调试浏览器的 WebRTC 播放器。第三类是项目负责人,在正式采购或自研之前,想先验证延迟、并发数和网络穿透情况。
2.2 能解决什么问题
RTMP 在直播推流端非常成熟,OBS、ffmpeg、各式编码器都支持,但浏览器原生不支持 RTMP 播放。WebRTC 则反过来,浏览器原生支持低延迟播放,但推流接入不如 RTMP 方便。rtmp2webrtc 测试环境就是把两者优势拼起来:推流走 RTMP,播放走 WebRTC,服务端负责协议转换。
典型流程:OBS 或 ffmpeg 把 RTMP 流推到服务器,SRS 或同类服务接收后转成 WebRTC SDP 会话,浏览器通过 WebRTC 拉流播放。这个方案对比 HLS 的明显优势是延迟可以做到秒级以内甚至更低,但也对网络环境有更高要求。
2.3 不适合什么场景
如果目标是千万级用户直播,需要更完整的 CDN 方案,本文的测试环境只适合验证,不适合直接承载大规模线上流量。如果推流源和播放端都在同一个局域网,测试结果会很好看,但公网环境下的 NAT 穿透、防火墙策略都需要单独验证。
另外,如果视频内容涉及人脸、声音、版权素材或企业内部敏感画面,测试时必须确保素材已获得合法授权,并在私有测试网络中运行,不能把未授权的直播内容直接推到公网服务。
3. rtmp2webrtc 测试环境准备与前置条件
3.1 操作系统与硬件
测试环境建议使用 Linux。常见的 Ubuntu、Debian、CentOS 都支持,如果使用麒麟、统信等国产操作系统,也可以按 Debian 系或 RPM 系的思路安装依赖,注意个别包名可能会不同。建议配置:
- CPU:2 核以上
- 内存:4GB 及以上
- 磁盘:至少 20GB 空闲空间
- 网卡:千兆网口或虚拟网络
- 防火墙:放行 TCP 1935(RTMP)、TCP 1985(HTTP API)、TCP 8080(HTTP 播放)、UDP 8000(WebRTC 媒体端口,SRS 默认范围)
没有 GPU 也没关系,rtmp2webrtc 协议转换的负载主要落在 CPU 和网络上。如果你后续要加转码、转封装或更多并发路数,再考虑 GPU 或更好的 CPU。
3.2 软件依赖
如果你的目标是 Docker 启动,只需要安装 Docker 和 Docker Compose。使用以下命令检查 Docker 是否可用:
docker --version
docker compose version
如果要用二进制方式启动,需要准备:
- Linux 基础环境
- wget 或 curl 下载工具
- 开放上述端口
- 可选:git 拉取配置示例
对于推流端,需要安装 ffmpeg 或 OBS Studio。ffmpeg 用于命令行推流,OBS 用于可视化推流。播放端使用 Chrome 或 Edge 浏览器即可,不需要额外插件。
4. 部署启动与协议转换服务配置
4.1 Docker 方式启动测试环境
Docker 是搭建测试环境最快的方式。SRS 官方镜像包含 RTMP 和 WebRTC 支持,直接用 docker run 启动一个容器即可。
先为测试环境创建目录:
mkdir -p /opt/rtmp2webrtc-test
cd /opt/rtmp2webrtc-test
然后创建 docker-compose.yml:
services:
srs:
image: registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5
container_name: srs-rtc-test
restart: unless-stopped
ports:
- "1935:1935/tcp" # RTMP 推流端口
- "1985:1985/tcp" # HTTP API 端口
- "8080:8080/tcp" # HTTP 播放或静态页面端口
- "8000:8000/udp" # WebRTC 媒体端口
volumes:
- ./conf:/usr/local/srs/conf
- ./logs:/usr/local/srs/objs
启动服务:
docker compose up -d
查看启动日志:
docker logs -f srs-rtc-test
看到类似
start server successfully
的日志,说明服务已经起来了。注意不同版本镜像的路径可能不同,如果挂载配置目录后无法启动,先去掉 volumes,用镜像默认配置启动,确认没问题再替换配置。
4.2 二进制方式启动
如果你不想用 Docker,也可以下载 SRS 源码编译或直接使用 release 包。这里给一个通用思路:
# 下载 5.0 版本源码示例,实际版本号以官方 release 为准
git clone -b develop https://gitee.com/ossrs/srs.git
cd srs/trunk
./configure --with-rtc
make
编译完成后启动:
./objs/srs -c conf/rtc.conf
RTC 配置的核心点是开启 WebRTC 并配置候选地址。如果直接用默认配置,在部分云服务器上会因为候选地址不对导致 WebRTC 无法播放。建议准备一个独立的 rtmp2webrtc.conf:
listen 1935
max_connections 1000
daemon off
srs_log_tank console
http_api {
enabled on;
listen 1985;
}
http_server {
enabled on;
listen 8080;
}
rtc_server {
enabled on;
listen 8000;
# 公网环境必须配置候选 IP,改成你的服务器公网 IP 或内网 IP
candidate $CANDIDATE_IP;
}
vhost __defaultVhost__ {
rtc {
enabled on;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
}
启动命令要带上环境变量:
CANDIDATE_IP=192.168.1.100 ./objs/srs -c conf/rtmp2webrtc.conf
注意:
$CANDIDATE_IP
在 SRS 配置中会被环境变量替换,实际使用时把 IP 改成测试机可被播放端访问到的地址。如果播放端和服务器在同一局域网,填内网 IP;如果跨公网,填公网 IP,并确保 UDP 8000 端口能到达服务器。
4.3 验证服务端口
服务启动后,检查端口监听状态:
ss -lntup | grep -E "1935|1985|8080|8000"
预期能看到 TCP 1935、TCP 1985、TCP 8080 和 UDP 8000 都在监听。如果只有部分端口在监听,检查配置是否启用了对应模块。
5. 功能测试与效果验证
5.1 准备一路测试视频源
用 ffmpeg 生成一路稳定的测试视频流,不依赖摄像头:
ffmpeg -re -f lavfi -i testsrc2=size=1280x720:rate=25 \
-f lavfi -i sine=frequency=440:sample_rate=44100 \
-vcodec libx264 -preset veryfast -tune zerolatency \
-acodec aac -shortest \
-f flv rtmp://127.0.0.1:1935/live/test
这条命令会生成 720p 的测试画面和 440Hz 音频,以流模式推送到 SRS。如果 ffmpeg 没有 libx264,也可以改用
-c:v libopenh264
或先不推音频。
5.2 查看 RTMP 推流是否成功
推流命令保持运行后,打开另一个终端,请求 HTTP API 查看流列表:
curl http://127.0.0.1:1985/api/v1/streams/
返回 JSON 中能搜索到
app
为
live
、
name
为
test
的流信息,说明 RTMP 推流已经成功进入服务。
5.3 验证 WebRTC 播放
浏览器输入 SRS 自带的播放页面:
http://127.0.0.1:8080/players/rtc_player.html
在页面中填写 SDP 播放地址,一般格式为:
webrtc://127.0.0.1:8080/live/test
点击播放后,如果页面出现视频画面和声音,说明 RTMP 到 WebRTC 的链路已经打通。这个测试的关键是确认播放端到服务端的 UDP 8000 端口可达,如果画面一直转圈,优先排查防火墙和 candidate 配置。
5.4 测试延迟表现
为了观察延迟,可以用手机或电脑打开一个秒表计时器,同时录屏显示推流端时钟和播放端时钟,比较两边的秒数差。更简单的办法是在 OBS 中添加一个动态时钟源,推流后在浏览器里观察延迟。
需要注意:
- 局域网环境下延迟会比较低,受网络抖动影响小。
- 公网环境下延迟受带宽、丢包和 UDP 转发策略影响。
- SRS 默认 WebRTC 配置偏重实时性,如果延迟异常,检查推流编码参数,避免 B 帧和过长 GOP。
5.5 多路流并发测试
rtmp2webrtc 测试环境可以验证多路能力。用脚本启动多路 ffmpeg 推流:
for i in $(seq 1 10); do
ffmpeg -re -f lavfi -i testsrc2=size=1280x720:rate=25 \
-vcodec libx264 -preset veryfast -tune zerolatency \
-f flv "rtmp://127.0.0.1:1935/live/stream_${i}" \
> /dev/null 2>&1 &
done
然后通过 API 查看:
curl http://127.0.0.1:1985/api/v1/streams/ | python3 -m json.tool | grep name
此时能观察到多路流同时在线。重点观察 CPU 和内存变化,如果出现推流断连或播放延迟增大,说明并发量已经接近测试机瓶颈。
6. RTMP to WebRTC 测试环境接口 API 调用示例
一个值得固化的能力是 HTTP API。SRS 的控制接口在 1985 端口,可以查询流信息、客户端信息和执行踢流操作。
6.1 查询流列表
curl http://127.0.0.1:1985/api/v1/streams/
返回结果包含
streams
数组,主要字段有
app
、
name
、
vhost
。可以用 jq 提取:
curl -s http://127.0.0.1:1985/api/v1/streams/ | jq '.streams[] | {app, name}'
如果 jq 没安装,用 python3:
curl -s http://127.0.0.1:1985/api/v1/streams/ | python3 -c "import sys,json;d=json.load(sys.stdin);[print(s['vhost'], s['app'], s['name']) for s in d.get('streams',[])]"
6.2 查询播放客户端
curl http://127.0.0.1:1985/api/v1/clients/
这个接口返回所有连接的客户端信息,可以区分推流客户端和播放客户端。不同版本的字段名可能稍有差异,以实际返回为准。
6.3 关闭指定流
如果需要自动清理测试流,可以调用踢流接口。SRS 的踢流 API 是删除对应的流连接:
curl -X DELETE http://127.0.0.1:1985/api/v1/clients/<client_id>
这里的
<client_id>
需要先从 clients 接口中拿到。注意不要在生产环境随意调用,测试环境可以放心验证。
6.4 Python 集成示例
一个通用的 RTMP 状态检查脚本可以这样写:
import json
import subprocess
import sys
def get_streams(api_base: str) -> list:
url = f"{api_base}/api/v1/streams/"
result = subprocess.run(["curl", "-s", url], capture_output=True, text=True)
data = json.loads(result.stdout)
return data.get("streams", [])
if __name__ == "__main__":
api_base = sys.argv[1] if len(sys.argv) > 1 else "http://127.0.0.1:1985"
for stream in get_streams(api_base):
print(stream["app"], stream["name"])
这段代码没有引入 requests,只依赖 curl 和 Python 标准库,适合在最小测试环境里运行。实际项目可以换成 requests 或 httpx。
7. 资源占用与性能观察方法
rtmp2webrtc 测试环境的核心资源指标有三个:CPU、内存、网络带宽。显存在这里不参与计算,除非你额外启用 GPU 转码。
7.1 观察 CPU 和内存
用 top 或 htop 观察进程占用:
top -p $(pgrep -f srs)
重点看 SRS 进程的 CPU 使用率。单路 720p 不转码的情况下,CPU 占用通常很低,但多路并发时会线性增长。如果 CPU 占用突然升高,检查是不是有其他服务抢占了端口或系统在做日志写盘。
内存方面,SRS 默认占用不高。但如果 WebRTC 播放客户端很多,每个会话都会持有一定的缓存,内存占用也会增加。更稳妥的判断是:先跑 1 路,记录内存;再跑到 10 路,对比差值,就能估算单条流的资源成本。
7.2 观察网络带宽
WebRTC 媒体走 UDP 8000 端口,推流走 TCP 1935。用
ss -tunap
查看会话:
ss -tunap | grep -E "1935|8000"
如果要看实时流量,可以用
iftop -i eth0
或
nload
。如果推流端网络上行受限,播放端会明显卡顿;如果服务器带宽跑满,需要限流或降低码率。
7.3 降低资源占用的方法
如果测试机性能较弱,可以这样调整:
- 推流端降低分辨率:从 1080p 降到 720p 或 480p。
-
降低码率:在 ffmpeg 中设置
-b:v 800k。 - 减少并发路数。
- 关闭 WebRTC 转码,保持直转模式。
- 将日志级别从 debug 调回 info 或 warn,减少日志写盘压力。
7.4 端口与进程残留排查
测试过程中经常遇到端口冲突或残留进程。可以用以下命令清理:
killall srs
docker compose down
如果端口被占用,用
ss -lntup
找到 PID,确认后再停止。不要盲目 kill 系统进程。
8. rtmp2webrtc 测试环境常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Docker 启动失败 | 镜像拉取失败或端口被占用 | 检查 docker logs | 更换镜像源或释放端口 |
| RTMP 推流连不上 1935 | 防火墙未放行 TCP 1935 | ss -lntup 检查监听 | 放行端口或修改监听地址 |
| 推流成功但浏览器无法播放 WebRTC | 服务器 candidate 配置错误 | 检查 rtc.conf 中 candidate | 配置正确的可访问 IP |
| UDP 8000 不通 | 云安全组未放行 UDP | 从外部 telnet 无法测试 UDP | 在安全组和本机防火墙同时放行 UDP 8000 |
| 播放画面黑屏无声音 | 推流编码格式或 GOP 过大 | 查看 ffmpeg 日志 | 使用 H.264 + AAC,关 B 帧 |
| API 接口返回 401 | 开启了鉴权 | 检查 http_api 配置 | 测试环境可先关闭鉴权 |
| 多路并发后卡顿 | CPU/带宽不足 | top、iftop 查看 | 降低码率或减少并发 |
| 浏览器提示 WebRTC 不支持 | 浏览器版本过旧 | 更换 Chrome/Edge 最新版 | 升级浏览器 |
| 播放延迟越来越大 | 推流端有 B 帧或缓存堆积 | 观察 ffmpeg 输出 |
加
-tune zerolatency
参数
|
按照从上到下的顺序排错,基本能覆盖大部分问题。最常踩的坑是安全组只放行 TCP,忘记放行 UDP 8000。WebRTC 媒体面是 UDP,只要 UDP 不通,页面即使显示 SDP 交换成功也无法出流。
9. 最佳实践与使用建议
9.1 先跑通最小链路,再扩展复杂度
第一次搭建不要一上来就加鉴权、转码、多路回调。先把 OBS 或 ffmpeg 推到 SRS,再用浏览器播放 WebRTC,确认链路通了,再逐个加功能。最小链路可以只保留推流端口和 UDP 媒体端口。
9.2 统一目录与命名
建议把测试环境里的配置文件、推流脚本、日志和结果文件分开存放:
/opt/rtmp2webrtc-test/
├── conf/
├── log/
├── scripts/
├── capture/
└── docker-compose.yml
推流脚本统一使用变量管理流名,这样批量测试时不用每次都改命令。
9.3 依赖和版本要固定
测试环境最怕版本漂移。Docker 镜像如果写
latest
,之后拉取可能行为不同。建议固定到已知可用的镜像标签,并在 README 中记录测试日期、版本和结论。这样下次复现才不会踩到“上次能用这次不能”的问题。
9.4 接口服务要限定访问范围
SRS 的 HTTP API 默认没有鉴权,如果部署在公网,任何人都可以查询流列表或调用接口。测试环境建议只监听
127.0.0.1
或通过防火墙限制来源 IP。如果必须开放,要在前面加一层鉴权反向代理。
9.5 涉及版权和隐私的合规要求
测试推流内容尽量使用合成的测试画面,例如 ffmpeg 的
testsrc2
或公开的免费素材。不要用人脸、声音、影视剧片段、企业内部监控画面在没有授权的情况下推流。即使是测试环境,也要把合规意识带进去,否则后续接真实业务会留下隐患。
9.6 批量任务加日志和重试
如果要做批量推流测试,每个推流进程都最好重定向到独立日志文件:
ffmpeg ... > /opt/rtmp2webrtc-test/log/stream_${i}.log 2>&1
脚本里加上退出码判断,推流失败自动重试 1 到 3 次,避免测试结论被网络抖动误导。
10. 总结与下一步
rtmp2webrtc 测试环境的搭建并不复杂,关键是理解 RTMP 到 WebRTC 的协议转换路径:RTMP 负责稳定推流,WebRTC 负责低延迟播放,测试环境的重点是验证这条链路在目标网络条件下是否稳定。最先应该验证的两个点是:推流后 RTMP 流是否正常进入服务,以及浏览器在目标网络中能否通过 WebRTC 成功拉到画面。最容易踩的坑就是 UDP 8000 端口没有放行,或者 candidate 地址配置错误。
后续可以在这个测试环境上继续扩展:接入 OBS 的推流场景,测试移动端浏览器的播放效果,增加多路并发压测,或者在 SRS 前面加一层鉴权代理,把这套链路逐步推向真实的业务验证环境。建议把这套配置和结论整理成一份内部文档,方便后续复现和团队协作。
火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。
更多推荐
所有评论(0)