SRS搭建WebRTC转RTMP测试环境:从部署到并发验证

发布时间:2026/9/8 1:56:09
SRS搭建WebRTC转RTMP测试环境:从部署到并发验证 这次我们来看一个非常经典的流媒体测试场景WebRTC 转 RTMP。浏览器端用 WebRTC 推流低延迟、采集方便、不用装插件但推到服务端之后下游 CDN、直播平台、播放器大多只认 RTMP。于是中间这段“协议转换”就必须靠一台媒体服务器来承担。最常用的开源方案是 SRS本文就围绕 SRS 搭一套最小可用的 WebRTC 转 RTMP 测试环境从部署、推流、拉流、API 查询到批量并发验证一次讲清楚。这套环境搭好之后你可以直接在浏览器里推流然后通过 RTMP 地址拉到流也可以把它作为 WebRTC 网关把多路浏览器采集的流统一转成 RTMP 再转推给 CDN 或直播服务。整条链路对 GPU 没有依赖一台普通 Linux 服务器或虚拟机就能跑适合做功能验证、接口联调和并发摸底。下面直接进入正题。1. 核心能力速览先给一张表快速判断这套环境适不适合你的场景能力项说明项目类型流媒体协议网关 / 测试环境核心能力接收浏览器 WebRTC 推流输出 RTMP/HTTP-FLV 流推荐实现方案SRS 开源流媒体服务器硬件要求普通 x86/ARM Linux 服务器或虚拟机CPU 为主GPU 依赖不依赖 GPU关键端口TCP 1935、TCP 1985、TCP 8080、UDP 8000支持平台Linux 发行版、麒麟等国产系统编译或 Docker 方式、macOS启动方式命令行启动 / Docker 启动API 能力SRS HTTP API可查询流列表、删除流批量任务支持多路 WebRTC 流并发转 RTMP适合场景浏览器直播推流、Web 端低延迟采集、CDN 转推测试、协议联调从这张表可以看到这套环境的门槛很低不需要 GPU不需要昂贵的采集卡浏览器本身就是采集端。核心工作是把 SRS 配置正确、把端口放通、把流名对应上。2. 适用场景与使用边界先讲清楚这套环境解决什么问题省得你部署完发现方向不对。适用的场景浏览器推流到直播链路用户打开网页通过摄像头或屏幕共享采集画面WebRTC 推到 SRSSRS 再以 RTMP 分发给播放器或 CDN。低延迟采集网关WebRTC 本身适合低延迟互动但下游不需要低延迟只需要稳定分发这时用 RTMP 出口最方便。协议联调测试验证 WebRTC 推流端、媒体服务器、RTMP 播放端三者能否稳定打通为正式上线提供依据。国产化环境验证在麒麟等系统上验证流媒体服务能否编译、运行为后续项目选型做技术储备。不适合的场景也要说明白如果你要的是大规模低延迟直播比如连麦、万人观看的互动直播单纯 WebRTC 转 RTMP 不够还需要完整 CDN 分发方案。如果要做复杂混流、转码、画中画SRS 只是基础转发需要再挂 FFmpeg 或自研处理链路。如果只是做录像回放可以直接走 HTTP-FLV 或 HLS不一定非要转 RTMP。使用边界方面有一点必须提醒测试用的视频素材、摄像头画面、屏幕共享内容都要确保有合法授权。尤其涉及人脸、声音、版权视频时需要获得相关权利人许可。WebRTC 采集的可能是会议室、桌面、业务系统界面转推到外部 RTMP 服务之前要确认是否符合所在单位的安全管理规定。3. 测试环境架构与协议分析先看整条链路是什么样浏览器WebRTC 推流 │ UDP / SRTP ▼ SRS 媒体服务器 │ RTMP / TCP ▼ FFplay / VLC / CDN / 直播平台推流端是浏览器通过 WebRTC 的 getUserMedia 采集音视频经过 ICE 协商建立连接再通过 SRTP 加密通道推送媒体数据。SRS 作为服务端接收后在内部把流对象统一管理并提供 RTMP 出口。为什么不能省掉中间这层WebRTC 是面向实时通信的协议传输层主要走 UDP端口动态协商使用 DTLS/SRTP 加密。RTMP 是直播分发领域的老牌协议走 TCP 长连接握手成功后持续推流。浏览器不能直接对 CDN 推 RTMPCDN 也不能直接从浏览器拉 WebRTC。所以需要一台媒体服务器做协议适配。从协议转换的维度看SRS 做的事情是通过 WebRTC 协议接收浏览器的 SDP Offer完成 DTLS/ICE/SRTP 协商。接收音视频 RTP 包解包后进入内部流管理。把同一路流以 RTMP 格式提供给下游不走转码流程保证低延迟。因此这套环境是“协议转换 流复制”不是“转码重编码”。如果你在测试中发现 CPU 极高要考虑是不是哪里触发了软转码。4. 环境准备与前置条件搭建这个测试环境需要准备以下资源资源要求服务器一台 Linux 服务器或虚拟机1 核心 2GB 内存起步建议 2 核 4GB操作系统Ubuntu、CentOS、Rocky Linux、麒麟 V10 等 Linux 发行版Docker可选如果走容器部署需要安装 Docker浏览器推荐 Chrome/Edge 最新版用于 WebRTC 推流播放器工具ffplay、VLC用于 RTMP 拉流验证网络规划放通 TCP 1935、TCP 1985、TCP 8080、UDP 8000服务器 IP 规划很重要后面所有地址都依赖它。假设这台服务器的访问地址是192.168.1.100那么规划如下端口协议用途1935TCPRTMP 拉流 / 转推1985TCPSRS HTTP API8080TCPSRS HTTP 服务、WebRTC 演示页面8000UDPWebRTC 媒体传输主端口在 Ubuntu/Debian 上放通防火墙sudo ufw allow 1935/tcp sudo ufw allow 1985/tcp sudo ufw allow 8080/tcp sudo ufw allow 8000/udp在 CentOS/Rocky/麒麟系统上如果使用 firewalldsudo firewall-cmd --permanent --add-port1935/tcp sudo firewall-cmd --permanent --add-port1985/tcp sudo firewall-cmd --permanent --add-port8080/tcp sudo firewall-cmd --permanent --add-port8000/udp sudo firewall-cmd --reload如果只是内网测试可以直接把防火墙临时关掉做快速验证但接通之后再逐步收拢端口避免留出风险面。5. 部署 SRS 并启用 WebRTC 转 RTMP5.1 使用 Docker 快速启动最简单的部署方式是用 SRS 官方镜像。先把配置文件放到宿主机比如在/opt/srs/rtc.conf写入以下内容listen 1935; max_connections 1000; daemon off; srs_log_tank console; rtc_server { enabled on; listen 8000; # 重要修改为服务器对浏览器可达的 IP candidate 192.168.1.100; } vhost __defaultVhost__ { rtc { enabled on; } http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } }这里有一个关键点candidate必须写浏览器能访问到的 IP。如果服务器有多个网卡或者服务器在 NAT 后面这个 IP 填错会导致浏览器推流时 ICE 协商失败表现为一直“连接中”。测试环境建议先填内网 IP跑通后再处理公网映射。启动 Docker 容器docker run -d --name srs-rtc \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ -p 8000:8000/udp \ -v /opt/srs/rtc.conf:/usr/local/srs/conf/rtc.conf \ ossrs/srs:5 \ ./objs/srs -c conf/rtc.conf国内服务器如果拉镜像慢可以给 Docker 配置镜像加速或者使用阿里云镜像仓库地址。启动后确认容器状态docker ps | grep srs-rtc5.2 麒麟等国产系统源码编译方式没有 Docker 或不打算用容器的环境可以源码编译 SRS。以麒麟 V10 为例先安装基础编译工具sudo yum install -y gcc gcc-c make gperf pkg-config git然后拉取源码并编译git clone -b develop https://github.com/ossrs/srs.git cd srs/trunk ./configure make编译完成后启动./objs/srs -c conf/rtc.conf需要注意源码编译时间取决于机器性能一般几分钟到二十分钟不等。麒麟 V10 这样的国产系统只要内核是 Linux、glibc 版本不太旧通常可以正常编译运行。如果./configure阶段提示缺少某个依赖安装对应的-devel包即可。5.3 检查服务启动状态启动之后检查端口是否监听成功ss -lntup | grep -E 1935|1985|8080|8000如果daemon off配置生效日志会直接打到终端。看到类似下面的输出说明服务已经就绪SRS 5.0 ... server main thread started, pid...再调用 HTTP API 确认curl http://127.0.0.1:1985/api/v1/streams/此时没有任何流返回结果是一个空列表或包含空streams字段的 JSON。这就说明 API 服务可用。6. 功能测试与效果验证环境跑起来之后先做一轮端到端验证。建议遵循“先推流、再拉流、再查 API、再写脚本”的顺序不要跳步骤。6.1 浏览器 WebRTC 推流测试推流地址格式如下webrtc://192.168.1.100/live/test其中live是 app 名称test是流名称。打开 SRS 自带的 WebRTC 推流演示页面在页面上填写这个地址然后授权浏览器调用摄像头或麦克风。如果浏览器直接拒绝摄像头权限检查两点页面是否通过localhost或127.0.0.1访问。页面是否通过 HTTPS 提供服务。浏览器安全策略要求远程地址必须走 HTTPS 才能调用摄像头、麦克风。测试环境如果只有 HTTP可以用localhost回环地址访问演示页面或者临时配置自签名证书。这个问题非常常见不是 SRS 的问题是浏览器权限策略。推流成功后SRS 控制台日志会打印新流加入的信息。回到 API 查询curl -s http://127.0.0.1:1985/api/v1/streams/ | python3 -m json.tool返回结果里应该能看到app为live、name为test的流。这是判断 WebRTC 推流是否进到服务端的核心标准。6.2 RTMP 拉流验证推流端跑通后再验证 RTMP 出口。使用 ffplay 拉流ffplay -fflags nobuffer -analyzeduration 1000000 -i rtmp://192.168.1.100/live/test如果画面正常出图说明 WebRTC 到 RTMP 的协议转换已经生效。没有 ffplay 时用 VLC 打开同一个地址也能验证。也可以只做探测不改动播放器环境ffprobe -v error -show_entries streamcodec_name -of csvp0 rtmp://192.168.1.100/live/test输出里有h264、aac之类的内容说明流数据是完整的。6.3 延迟观察WebRTC 端到端延迟很低但经过 RTMP 分发后播放端会因为缓冲策略产生一定延迟。测试时可以在浏览器采集画面中放一个毫秒计时器然后用手机或另一台电脑播放 RTMP 流对比两端时间差。这个测试能直观看出“低延迟采集 RTMP 分发”的延迟构成。需要注意的是不同播放器的缓冲策略差异很大延迟数据只能作为参考。要量化评估应该在相同播放器、相同网络条件下多次对比。6.4 自动化验证脚本手动作过一轮后建议写一个 Python 脚本做自动化验证。脚本思路很简单从 SRS API 拉取流列表对每一路流执行 ffprobe 探测判断 RTMP 是否可拉流。import requests import subprocess SRS_API http://127.0.0.1:1985/api/v1/streams/ def get_streams(): resp requests.get(SRS_API, timeout5) resp.raise_for_status() return resp.json().get(streams, []) def check_rtmp_stream(rtmp_url: str) - bool: cmd [ ffprobe, -v, error, -show_entries, streamcodec_name, -of, csvp0, rtmp_url ] try: result subprocess.run(cmd, capture_outputTrue, textTrue, timeout15) return result.returncode 0 except Exception as exc: print(f [WARN] ffprobe执行异常: {exc}) return False if __name__ __main__: streams get_streams() print(f当前SRS流数量: {len(streams)}) for s in streams: app s.get(app, ) name s.get(name, ) rtmp_url frtmp://127.0.0.1:1935/{app}/{name} if check_rtmp_stream(rtmp_url): print(f [OK] RTMP可拉流: {rtmp_url}) else: print(f [FAIL] RTMP无法拉流: {rtmp_url})把脚本放到测试服务器上配合定时任务就能实现“定时检查 WebRTC 转 RTMP 链路是否健康”。实际使用时rtmp://127.0.0.1要按需替换成可从脚本所在机器访问的地址。7. 接口 API 与批量任务7.1 SRS HTTP API 查询流列表SRS 的 HTTP API 默认跑在 TCP 1985 端口常用接口如下接口方法说明/api/v1/streams/GET查询所有流/api/v1/streams/{id}DELETE删除指定流/api/v1/clients/GET查询客户端连接查询当前所有流的命令curl -s http://127.0.0.1:1985/api/v1/streams/ | python3 -m json.tool返回结果中的核心字段字段说明app应用名对应推流地址里的第二段name流名称id流在 SRS 内部的 ID删除流时使用这套 API 不需要额外鉴权所以在测试环境要限制访问来源。如果部署在公网建议用防火墙把 1985 端口限制为内网 IP 或跳板机 IP。7.2 多路并发与批量验证WebRTC 转 RTMP 最常见的问题是并发多了之后UDP 端口和 CPU 资源是否撑得住。测试环境里可以这样验证开多台浏览器或另开多个隐私窗口分别推流到不同流名webrtc://192.168.1.100/live/stream-01 webrtc://192.168.1.100/live/stream-02 webrtc://192.168.1.100/live/stream-03通过 API 一次性查看所有流curl -s http://127.0.0.1:1985/api/v1/streams/ | python3 -c import sys, json data json.load(sys.stdin) for s in data.get(streams, []): print(s[app], s[name]) 对每一路流执行 ffprobe 探测确认所有流都能走通 RTMP 出口。这一步可以直接复用上面的 Python 脚本只要把127.0.0.1:1985和127.0.0.1:1935换成实际地址。7.3 批量清理异常流联调测试时经常有推流端异常退出服务端保留大量僵尸流。这时候通过 API 删除流比重启服务快得多。先找出流 IDcurl -s http://127.0.0.1:1985/api/v1/streams/ | python3 -m json.tool再删除指定流curl -X DELETE http://127.0.0.1:1985/api/v1/streams/1如果异常流太多可以写个循环批量清理这里给一个 Python 片段做参考import requests SRS_API http://127.0.0.1:1985/api/v1/streams/ resp requests.get(SRS_API, timeout5) for s in resp.json().get(streams, []): if s.get(name, ).startswith(test-): stream_id s.get(id) if stream_id: requests.delete(f{SRS_API}{stream_id}, timeout5) print(fdeleted stream {stream_id})注意删除流会导致播放端和转推链路立即断开。批量清理前要确认不会影响正在使用的业务流。8. 资源占用与性能观察WebRTC 转 RTMP 属于实时媒体处理任务资源占用需要实际测试不能凭空拍脑袋。但从架构上可以做一个基本判断CPUSRS 纯协议转换情况下CPU 占用主要来自 SRTP 加解密和 RTP 包处理通常低于转码方案。如果引入 FFmpeg 转码CPU 会明显上升。内存每路流的缓冲和队列都会占用内存流数越多内存占用越高。带宽WebRTC 上行带宽决定推流质量RTMP 下行带宽决定分发给多少路播放端。并发播放越多出口带宽压力越大。UDP 丢包WebRTC 传输依赖 UDP网络丢包会直接导致画面卡顿、花屏甚至推流中断。测试时重点观察服务器网卡的 UDP 丢包统计。观察资源占用可以使用以下命令# 查看系统负载和内存 top # 查看 SRS 进程状态 ps aux | grep srs # 查看网络连接和端口 ss -s # 实时查看网卡流量 iftop -i eth0如果是 Docker 启动直接看容器资源docker stats srs-rtc做并发测试时建议每增加 10 路流记录一次 CPU、内存、带宽、UDP 丢包数据形成一张简单的性能趋势表。不要说“预估能支持多少路”而是用数据说话。9. 常见问题与排查方法问题现象可能原因排查方式解决方案浏览器推流一直显示连接中UDP 8000 端口不通或 candidate 配置错误检查防火墙、用 ss 查看监听端口放通 UDP 8000把 candidate 改为浏览器可达 IP页面拿不到摄像头权限页面不是 localhost 或未使用 HTTPS检查浏览器地址栏安全状态使用 localhost 访问或配置 HTTPSRTMP 拉流失败流名不一致或 SRS 未收到流通过 API 查询流列表核对 app/stream确保推流地址与拉流地址保持一致拉流黑屏或只有音频播放器缓冲策略问题或浏览器没有推视频轨换 ffplay 测试查看浏览器采集权限调整播放参数确认推流端选择了正确的摄像头API 返回空列表推流没有进入服务端查看 SRS 控制台日志检查 WebRTC 地址格式确认 app 与 stream 命名正确服务器有多个 IP推流连不上candidate 自动选择错误查看 SRS 日志中的候选地址在 rtc.conf 中显式指定 candidate国产系统编译 SRS 失败缺少编译依赖或 gcc 版本过旧查看 configure 报错信息安装 gcc、gperf、pkg-config 等编译工具多路并发时画面卡顿带宽不足或 UDP 丢包用 iftop、ethtool 查网卡状态增加带宽调整推流码率优化网络质量遇到问题时优先看 SRS 控制台日志。日志里如果出现ICE failed、DTLS failed之类的关键字基本可以确定是 UDP 端口或 candidate 配置问题。10. 最佳实践与使用建议第一次搭建这个测试环境时建议按下面的顺序推进先跑通最小链路再扩展并发。最小链路就是“一台 Linux 服务器 一个浏览器 一个 ffplay”只要这 3 个角色能串起来说明核心方向没有错。在测试环境管理上做好以下几点配置文件单独保存不要直接改 SRS 原始配置把rtc.conf放到/opt/srs/这样的独立目录方便备份和回滚。流命名统一规范例如live/stream-01、test/webrtc-01方便批量脚本过滤和管理。日志单独留存SRS 前台运行时可以直接重定向到文件./objs/srs -c conf/rtc.conf /var/log/srs.log 21API 端口不要暴露到公网1985 端口控制流列表和流删除如果被外部访问可能被恶意删除。用防火墙限制来源 IP。批量任务加日志和重试上面给的 Python 脚本只是验证框架生产环境最好把每次探测结果写入日志文件对失败项进行重试。涉及授权素材测试摄像头、屏幕共享、录制画面都要保证来源合法。如果是公司业务数据要评估是否符合保密要求。关于并发测试建议先压测单路推流的稳定性再逐步增加流数。整个过程中记录 CPU、内存、带宽变化找到拐点。不要追求“服务端支持几千路”这种结论测试环境的意义是验证链路功能和发现瓶颈不是做极限压力测试。11. 总结与下一步这套 WebRTC 转 RTMP 测试环境最值得先验证的就是三件事UDP 端口通不通、candidate 配得对不对、RTMP 地址能不能拉流。把这三件事跑通整个链路就基本成型了。最容易踩的坑集中在网络侧而不是 SRS 本身浏览器能推流但拉不到流时优先检查流名和端口。下一步可以继续扩展的方向在 SRS 与 CDN 之间加 RTMP 转推验证公网分发链路。引入 FFmpeg 对 RTMP 流做转码、录制扩展测试场景。把监控脚本接入告警系统对流数量、拉流成功率做指标采集。基于 SRS HTTP API 写一个简单的控制台实现推流状态可视化和异常流一键清理。这套环境本身不复杂但它是理解 WebRTC 和 RTMP 协议转换很好的起点。建议把配置文件和验证脚本都保存好后续做协议联调、直播测试时可以直接复用。