
RTMP转 WebRTC 这个组合放在几年前还属于“能用但折腾”的方案现在已经是低延迟直播测试的标配路径。推流侧继续用 RTMP——OBS、硬件编码器、现有推流 SDK 都支持播放侧换成 WebRTC——浏览器原生能力不需要装 Flash也不需要额外 App延迟可以做到秒级以内。关键在中间那一层流媒体服务把 RTMP 拉进来的流转成 WebRTC 可播放的会话。这次我们完整过一遍 rtmp2webrtc 测试环境的搭建过程从环境准备、服务启动到 FFmpeg 模拟推流、浏览器 WebRTC 拉流最后用直接方法对比延迟、排查链路问题。整套流程在不同 Linux 发行版上通用麒麟操作系统等国产化环境我会单独标出需要注意的点。不涉及复杂的集群和商业化调度目标是让你有一台机器就能把“RTMP 进、WebRTC 出”的链路跑通并且知道每一步怎么验证、出了问题从哪里查。如果你负责直播平台的低延迟改造、在线课堂或者远程协作类项目或者刚接触 WebRTC 网关但不想直接跳到源码级别这篇文章可以先收藏起来照着做。1. RTMP 转 WebRTC 核心链路速览RTMP 和 WebRTC 是两套差异很大的协议。RTMP 基于 TCP 长连接推流简单稳定几乎所有推流端都支持但播放延迟通常在 3 到 10 秒WebRTC 基于 UDP 和 ICE/DTLS/SRTP 一套组合播放端只需要浏览器支持延迟有机会压到 1 秒以内。Rtmp2webrtc 测试环境的核心就是在服务端同时处理这两种协议一端接收 RTMP 推流另一端把媒体数据转成 WebRTC 拉流会话。从测试环境的角度看整套链路可以拆成三块模块作用常用实现推流端产生音视频流并通过 RTMP 推送FFmpeg、OBS Studio、硬件编码器流媒体服务接收 RTMP 流转封装并协商 WebRTCSRS、ZLMediaKit、MediaMTX播放端通过 WebRTC 拉流并渲染Chrome、Edge、自定义 Web 播放器如果用 SRS 作为参考方案它自身带 HTTP 管理和播放测试页部署最简单的方式是 Docker 跑一个容器把 RTMP、HTTP API、WebRTC 几个端口映射出来。也可以用源码编译适合需要二次修改或者跑在特殊 CPU 架构上的场景。1.1 参考开源项目的选择SRS、ZLMediaKit、MediaMTX 都能做 RTMP 到 WebRTC 的转换但侧重点不同。项目特点适合场景SRS功能全社区活跃自带播放器和 HTTP API5.0 之后对 WebRTC 支持很完整标准低延迟直播测试、教育活动、对外演示ZLMediaKitC 高性能支持 GB28181/RTSP/RTMP/WebRTC 多协议API 设计灵活安防、监控、多协议接入MediaMTX轻量、单二进制文件配置简单快速验证协议转换、嵌入式设备本文以 SRS 为例展开因为它在 rtmp2webrtc 这块的配置最直观官方文档也齐全。但下面的验证思路和排查方法对另外两个项目同样适用。2. 适用场景与使用边界rtmp2webrtc 测试环境首先是一条验证链路不是一个生产直播平台。它真正解决的问题是你手上已经有 RTMP 推流端比如 OBS、无人机图传、硬件编码器但播放端需要低延迟体验不能容忍 HLS 那种 5 到 10 秒的延迟。测试环境先把这条链路从 0 到 1 跑通验证延迟是否达标、长时间运行是否稳定、网络波动下是否会出现花屏和卡顿。比较适合的场景包括在线课堂和互动教学老师端用 OBS 推 RTMP学生端在浏览器里低延迟观看。活动直播的导播台到播放页的传输导播台输出 RTMP网页播放器用 WebRTC 拉流。企业内部远程巡检、设备画面回传推流设备支持 RTMP 但监控大屏需要秒级延迟。不意味着适用所有场景。如果是要做大规模公网分发WebRTC 对 NAT 穿越和服务端 ICE 配置的要求比 HTTP-FLV 高CDN 覆盖成本也更高这类场景用 WebRTC 网关的成本要重新评估。如果只是简单的录播回放HLS 仍然是更稳定的方案不需要引入 WebRTC。使用边界必须明确测试环境涉及到的视频画面、音频内容、人物肖像都需要有合法授权推流素材不要使用未经授权的影视剧、音乐、他人肖像。如果测试环境部署在可公网访问的服务器上一定要加推流鉴权和播放页访问控制避免被恶意推流或劫持资源。直播相关内容如果对外公开还需要符合内容平台和监管要求这些在搭建环境时就应该同步考虑而不是等出现问题再补。3. 测试环境准备这个测试环境对硬件要求不高核心是能跑 Linux 服务、能跑 FFmpeg 推流、能打开浏览器。下面是通用检查清单具体版本号以你选用的项目官方文档为准。3.1 硬件与网络项目最低建议说明CPU2 核单路转流测试通常够用多人并发才需要更多核内存4 GB服务本身占用不高主要看系统和其他进程磁盘20 GB 空闲存放服务、依赖和测试录像网络本机回环或局域网第一轮测试建议用 127.0.0.1避免 NAT 干扰操作系统Linux x86_64也支持 ARM 架构需要对应编译参数如果你的机器是 Windows也可以用 WSL 或虚拟机跑 Linux 服务播放端浏览器仍用 Windows 下的 Chrome 访问。这样推流端在 Linux播放端在 Windows环境更接近真实局域网链路。如果部署环境是麒麟操作系统注意先确认系统架构是 x86_64 还是 aarch64下载对应架构的二进制或自行编译。麒麟的包管理器可能是 apt 系也可能是 yum 系依赖库名称会有差异。部署前先执行uname -m看架构再用系统自带的包管理器搜索依赖包名不要直接照搬 Ubuntu 的命令。3.2 软件依赖软件用途安装方式Docker快速启动流媒体服务官方脚本或发行版包管理器FFmpeg产生推流数据apt/yum 安装或官方 static buildChrome / EdgeWebRTC 播放验证官方安装包curl测试 HTTP API一般系统自带如果不用 Docker源码编译方式需要额外准备 gcc、make、cmake、libssl-dev、libsrtp-dev 等编译依赖。这个列表在不同系统上名字不完全一样漏掉依赖会在 configure 阶段报错到时候按提示补装即可。4. 安装部署与启动方式以下是通用部署步骤以 SRS 为例。实际使用时请以对应项目的官方 README 为准。4.1 Docker 方式启动这是最快的方式。先确保 Docker 已安装然后执行# 拉取并启动 SRS端口需要根据官方镜像文档确认 docker run --rm -p 1935:1935 -p 1985:1985 -p 8080:8080 \ -p 8000:8000/udp \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5各端口作用如下端口协议作用1935TCPRTMP 推流入口1985TCPHTTP API 和后台管理8080TCPWeb 播放器和测试页面8000UDPWebRTC RTP 媒体传输启动后终端会输出日志看到类似start server或者listen on 1935的日志基本说明服务起来了。然后用curl验证 HTTP APIcurl http://127.0.0.1:1985/api/v1/versions返回 JSON 里有版本号说明 HTTP API 可用。4.2 源码编译方式如果需要改代码或跑在特殊架构上可以走编译方式git clone https://github.com/ossrs/srs.git cd srs/trunk ./configure --full make ./objs/srs -c conf/rtmp2rtc.conf编译时间取决于机器性能通常在 10 到 30 分钟。编译完成后关键是检查配置文件。SRS 需要用以下配置同时开启 RTMP 和 WebRTC# rtmp2rtc.conf 核心片段实际参数以项目版本为准 listen 1935; max_connections 100; srs_log_tank console; rtc_server { enabled on; listen 8000; # 如果本机测试candidate 可以直接用 127.0.0.1 candidate 127.0.0.1; } vhost __defaultVhost__ { rtc { enabled on; } http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } }注意candidate这个参数。如果播放端和推流端都在本机回环地址可以写 127.0.0.1如果要跨设备测试需要改成服务器实际 IP 或公网 IP否则 WebRTC 协商阶段会拿到错误地址播放端连接失败。4.3 启动脚本与端口占用检查每次测试环境重启后端口占用最常见的错误是先启动了旧进程或者端口被其他服务占用。启动前检查# 查看相关端口是否被占用 ss -tulpn | grep -E 1935|1985|8080|8000如果端口被占用要么杀掉旧进程要么改配置换端口。推荐测试环境固定使用一套端口避免排查问题时记混。5. 功能测试与效果验证服务启动后开始验证完整链路。顺序是先确认推流能进来再确认 WebRTC 能播放最后做延迟对比。5.1 FFmpeg 推流测试用 FFmpeg 生成一段测试视频推流不需要提前准备素材文件# 生成测试画面1280x72030fpsH.264 AAC推送到 SRS ffmpeg -re -f lavfi -i testsrcsize1280x720:rate30 \ -f lavfi -i sinefrequency440:sample_rate44100 \ -c:v libx264 -preset veryfast -tune zerolatency -g 30 \ -c:a aac -b:a 128k \ -f flv rtmp://127.0.0.1/live/livestream参数里-tune zerolatency是低延迟编码关键-g 30表示每 30 帧一个关键帧便于 WebRTC 快速追帧。推流命令保持运行然后打开 API 查看流状态curl http://127.0.0.1:1985/api/v1/streams/如果返回的流列表里有livestream说明 RTMP 推流已经成功进入服务。这一步没通过就先不要往后走重点排查推流地址、端口、防火墙。5.2 WebRTC 播放验证浏览器打开http://127.0.0.1:8080/players/rtc_player.html填入 WebRTC 播放地址。SRS 的 WebRTC 地址格式一般是webrtc://127.0.0.1/live/livestream也可以直接在网页里选WebRTC模式点播放。如果页面出现测试画面并且音频能听到说明协议转换链路是通的。注意 Chrome 需要允许自动播放音频否则页面会静音。浏览器控制台如果有getUserMedia或 ICE 报错重点看 F12 有没有红色跨域错误。直接用 IP 访问一般没有跨域问题但如果你用了自定义域名需要在服务端配置 CORS 或改用同源部署。5.3 RTMP 播放与 WebRTC 播放延迟对比要验证 rtmp2webrtc 的价值最直接的方式是同一个推流分别用 RTMP 播放和 WebRTC 播放对比延迟。用 VLC 播放 RTMP 流vlc rtmp://127.0.0.1/live/livestreamVLC 上右键播放器选择“媒体信息”或者统计信息可以看到网络缓存和缓冲设置。默认 VLC 缓冲较大延迟会被放大这不是服务端的问题。用 SRS 自带的播放器页面选择HTTP-FLV播放再和WebRTC播放对比数据更有参考价值。一个简单的手动测延迟方法推流画面里放一个秒表或计时器用 OBS 添加文本源显示当前时间。同一台电脑上同时打开 FLV 播放页和 WebRTC 播放页。手机拍照或截图对比两个播放器显示的时间差。这种方法误差有点大但足够验证 WebRTC 是否明显比 FLV 更低延迟。正式压测时可以用摄像头拍摄秒表画面再用视频分析软件对比帧号。WebRTC 播放页如果已经出画面说明数据通路是通的。注意如果 WebRTC 播放页黑屏但后台没有报错先检查浏览器是否支持 H.264。部分系统自带浏览器只有 OpenH264 或 VP8 支持而 SRS 默认推的是 H.264需要编解码协商成功才会出画面。5.4 连续推流稳定性测试测试环境不止要验证“能不能通”还要验证“能不能稳”。建议做一次至少 30 分钟的连续推流# 持续推流 30 分钟观察服务端日志和播放端是否有断流 ffmpeg -re -f lavfi -i testsrcsize1280x720:rate30 \ -c:v libx264 -preset veryfast -g 30 \ -f flv rtmp://127.0.0.1/live/livestream同时开一个脚本周期请求 API记录流状态for i in $(seq 1 60); do curl -s http://127.0.0.1:1985/api/v1/streams/ | grep -q livestream \ echo $(date) streaming ok || echo $(date) stream lost sleep 30 done如果出现stream lost说明推流中断或服务异常结合服务端日志和推流端日志分段排查。5.5 多路流测试生产环境往往不止一路流。测试环境中至少要验证几路流并发推流和播放不互相影响# 同时推多路不同 stream 名的流 ffmpeg -re -f lavfi -i testsrcsize640x360:rate25 \ -c:v libx264 -preset veryfast -g 25 \ -f flv rtmp://127.0.0.1/live/stream1 ffmpeg -re -f lavfi -i testsrcsize640x360:rate25 \ -c:v libx264 -preset veryfast -g 25 \ -f flv rtmp://127.0.0.1/live/stream2多路流的重点不是“服务不会崩”而是“一路流出问题是否会拖垮其他流”。可以在测试中故意停掉一路推流观察另外一路是否正常。如果一路流异常导致全局卡顿说明服务配置或资源隔离还需要调整。6. 接口能力与接入方式rtmp2webrtc 测试环境虽然核心是验证链路但如果不提前验证接口能力和接入方式后面要接到自己的播放器或管理系统时容易反复返工。6.1 服务端 HTTP API以 SRS 为例通过 HTTP API 可以查询、管理流接口路径大致如下# 获取版本 curl http://127.0.0.1:1985/api/v1/versions # 获取全部流列表 curl http://127.0.0.1:1985/api/v1/streams/ # 踢掉指定流示例具体接口以项目文档为准 curl -X DELETE http://127.0.0.1:1985/api/v1/clients/{client_id}这类接口适合接进自己的后台用来展示直播列表、做流健康检查和自动踢流。测试环境阶段建议先把“获取流列表”这一个接口跑通后面的管理逻辑可以慢慢加。实际项目里接口返回字段会随版本变化调试时先看原始 JSON 结构再写解析代码。6.2 播放器接入方式播放器接入有三种方式测试环境建议都试一遍方式实现复杂度官方播放器页面浏览器直接打开 SRS 自带的 player 页面最简单只用来验证链路第三方播放器集成支持 WebRTC 的开源播放器如 webrtc-streamer、Janus Player中等需要按文档配置自研播放器基于 WebRTC API 封装自己的播放器最复杂但控制力最强如果只是做技术验证用官方播放器页面就足够。如果后续要嵌进业务系统至少要完成一次“把播放器集成到你自己的网页里”的试验重点验证跨域配置、地址生成规则、自动播放策略。6.3 录制备份测试环境的录像不是必需的但建议把推流源录制一份方便回看和排查问题。可以用 FFmpeg 从 RTMP 流拉流录制ffmpeg -i rtmp://127.0.0.1/live/livestream -c copy output.flv录制时注意磁盘空间长时间测试录像可能增长很快。测试环境建议录制 5 到 10 分钟即可没必要全部保留。7. 资源占用与性能观察rtmp2webrtc 测试环境的资源占用主要来自三部分流媒体服务本身、FFmpeg 推流进程、浏览器播放渲染。重点观察前两者。7.1 流媒体服务资源观察在推流持续运行的情况下用top或htop观察进程 CPU 和内存。SRS 这类事件驱动架构的服务在单路转流时 CPU 占用通常很低内存占用也不会太高。但具体数字取决于推流分辨率、码率、WebRTC 播放人数、GOP 大小、是否开启转码等不要以别人的数字直接套用以你本机测试为准。如果 CPU 占用异常升高优先检查是否误开了转码服务或者推流分辨率/码率设置过高。测试环境建议先跑 720p 或 1080p码率控制在 2 到 4 Mbps先把正常基线摸清再说高负载。7.2 网络与 UDP 端口WebRTC 播放依赖 UDP尤其是 8000 端口。跨网络测试时服务端防火墙、安全组、NAT 规则都必须放行 UDP。TCP 端口通而 UDP 端口不通是 WebRTC 测试中最常见的坑之一。排查方法推流正常播放页面长时间处于连接中优先看 UDP 端口是否可达。# 用 nc 测试 UDP 端口端口是否开放以实际输出为准 nc -uvz 127.0.0.1 8000如果服务端部署在云主机或内网需要注意 ICE candidate 配置。服务端拿到公网地址客户端才能穿过 NAT 直连。测试环境如果仅在局域网内candidate 配置成服务器内网 IP 即可。7.3 推流端与播放端的相互影响FFmpeg 推流进程本身也会占 CPU尤其是在低配机器上。测试环境最好把推流端放在一台机器流媒体服务和浏览器播放放另一台机器避免 FFmpeg 和浏览器抢 CPU导致结果偏差。如果只能一台机器至少观察一下 top 输出确认 FFmpeg 和流媒体服务不会因为 CPU 竞争出现推流中断或播放卡顿。7.4 降低资源占用的手段几个通用调优方向手段作用注意事项降低分辨率减少编码压力720p 足够验证链路增大关键帧间隔减少码率波动延迟会略微增加需要权衡关闭转码避免不必要的 CPU 开销推流编解码格式必须兼容限制播放人数减少服务端并发压力测试环境建议 1 到 2 个播放端定时清理录像避免磁盘写满用 cron 或手动清理到指定目录8. 常见问题与排查方法下面是这套测试环境最常见的问题和排查思路汇总成表格方便检索问题现象可能原因排查方式解决方案推流失败连接拒绝服务未启动或 RTMP 端口未监听检查日志用 ss 查看 1935 端口启动服务或检查监听端口推流失败认证失败推流鉴权开启但未传正确 token查看服务端日志检查推流地址参数关闭鉴权或配置正确鉴权参数WebRTC 播放黑屏播放端不支持 H.264或 ICE 协商失败浏览器 F12 控制台看日志检查 SDP 中的编解码和 candidate换浏览器或检查 UDP 端口WebRTC 播放卡顿网络丢包、带宽不足、GOP 设置过大推流端降低码率检查带宽占用增大关键帧频率或降低分辨率播放延迟忽高忽低服务端缓冲配置不合适对比 FLV 播放延迟确认是否 WebRTC 独有调整服务端缓冲和推流端编码参数8080 播放页打不开HTTP 服务未启动或端口被占用curl 测试 8080检查日志确认端口正确重启服务API 返回连接错误API 端口被防火墙拦截curl 本机先试再跨机器试关闭防火墙或放行端口多路流互相影响服务配置未针对多路流调优查看单路和多路时的 CPU/带宽差异调整并发参数或升级硬件浏览器自动播放被拦截浏览器策略限制手动点击播放按钮页面增加用户交互后播放最常用的排查手段就三个看服务端日志、看浏览器控制台、curl 接口验证。这三个信息都拿到手绝大多数问题都能定位到具体环节。日志查看方式# SRS 日志默认打在前台如果用 docker 运行用 docker logs docker logs --tail 100 container_id如果发现日志里反复出现握手失败或协商失败优先检查 candidate 配置和端口。如果是推流端报错看 FFmpeg 输出是连接问题还是编码问题通常它们会给出明确的错误码。9. 最佳实践与使用建议测试环境能跑通不等于生产环境能直接用。以下建议能帮你减少返工。9.1 第一次测试先小参数跑通先不要推 4K 高码率流先用 640x360 或 1280x720 的低码率流跑通整个链路。延迟、稳定性、资源占用这些指标在小参数下先拿到基线再逐步增加复杂度。如果一开始就上高参数出了问题很难分清是协议问题还是性能问题。小参数跑通后再验证高分辨率会更安心。9.2 保留一套最小可运行配置把推流命令、服务启动命令、播放地址、验证命令整理成一个 README 或脚本目录方便下次启动测试环境时直接照做。最小可运行配置包括一份可启动的配置文件、一条 FFmpeg 推流命令、一条播放验证方法、一个 API 检查步骤。不要再靠记忆拼命令。# 保存一个启动脚本示例 start_rtmp2webrtc_env.sh #!/bin/bash docker run --rm -d \ -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp \ --name rtmp2webrtc-test \ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 sleep 5 curl -s http://127.0.0.1:1985/api/v1/versions这个脚本只是一个雏形实际删改以你选择的项目和环境为准。9.3 输入素材、输出录像、服务端日志分目录管理测试环境很容易产生一堆碎文件测试视频、录像、日志、截图、配置备份。建议目录结构如下rtmp2webrtc-lab/ ├── configs/ # 服务配置和启动脚本 ├── inputs/ # 推流素材、测试图片 ├── outputs/ # 录像、截图 └── logs/ # 服务端日志每次测试前把目录清空或按日期建子目录避免把不同日期的测试结果搞混。9.4 批量验证和自动化需要做长时间稳定性测试时不要手动盯页面。写一个简单的 shell 或 Python 脚本定期请求 API记录流状态上下行码率等指标超过阈值就报警。API 接口返回的 JSON 结构可以先手动请求一次看清楚字段再写脚本。9.5 安全与合规操作清单推流鉴权一定要开启哪怕是测试环境防止被外部扫描到后恶意推流。WebRTC 播放页不要暴露到公网至少加一层访问密码或 IP 白名单。测试素材使用 FFmpeg 合成画面不要使用有版权的视频、音乐、影视片段。如果测试涉及真实人物画面确认本人同意在测试环境中使用。服务端日志可能包含 IP 和请求参数日志文件要注意访问权限及时清理。截图和录像不要超过测试需要的时间用完之后定期删除。10. 总结与下一步这次我们梳理了一条完整的 rtmp2webrtc 测试链路推流端用 FFmpeg 生成 RTMP 流流媒体服务负责协议转换播放端用浏览器验证 WebRTC再通过 API 和日志做状态和能力验证。整套测试环境跑下来最值得关注的是四个点链路是否能跑通、延迟是否符合预期、长时间运行是否稳定、接口是否能满足后续接入需求。先从最小配置开始启动服务后用 FFmpeg 推一条测试流再打开 WebRTC 播放页验证画面和声音最后对比 FLV 延迟和 WebRTC 延迟。这四步里面最容易踩坑的就是 WebRTC 播放器连不上服务问题根源往往在 UDP 端口没放行或 candidate 配置不对排查时优先看这两处能节省不少时间。下一步扩展方向可以从三段走把推流端从 FFmpeg 换成 OBS 或硬件编码器验证真实设备接入在服务端增加鉴权和播放页控制贴近业务使用方式再往后可以评估 SRT 协议、WHIP 协议等其他低延迟接入方式对比不同协议在延迟、稳定性和跨网能力上的差异。测试环境本身就是用来快速验证这些东西的链路跑顺之后再往上叠加业务心里就有底了。