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 前面加一层鉴权代理,把这套链路逐步推向真实的业务验证环境。建议把这套配置和结论整理成一份内部文档,方便后续复现和团队协作。

Logo

火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。

更多推荐