RTMP转WebRTC低延迟播放:基于SRS的测试环境搭建实战

发布时间:2026/9/8 11:32:01
RTMP转WebRTC低延迟播放:基于SRS的测试环境搭建实战 之前在项目中需要快速验证一条“RTMP 推流 WebRTC 低延时播放”的链路是否可行结果卡在测试环境搭建上资料很散有的讲 RTMP 推流有的讲 WebRTC 播放却没有人把中间转换层说清楚。折腾了两天才跑通第一帧画面后面整理成一套可复用的 rtmp2webrtc 测试环境搭建流程正好分享出来。如果你也正在做直播、音视频通话、低延迟播放相关的验证这篇文章可以帮你少踩很多坑。本文会从 RTMP 和 WebRTC 各自解决什么问题讲起接着给出测试环境的目标架构和组件选型然后基于开源流媒体服务器搭建一套完整的 rtmp2webrtc 测试环境包含 Docker 部署、推流、播放、自动化验证、常见报错排查以及测试环境落地时的一些工程建议。新手可以按步骤从头跟到尾有经验的开发者可以直接跳到第 4 节复制部署命令。1. RTMP 与 WebRTC 核心概念1.1 RTMP 是什么RTMP 全称 Real-Time Messaging Protocol也就是实时消息传输协议。它最早由 Macromedia 设计后来 Adobe 持续维护曾经是直播行业事实上的标准协议。目前常见的 RTMP 推流工具 OBS、FFmpeg以及各大直播平台的服务端大多都支持 RTMP 协议。RTMP 基于 TCP 传输默认端口是 1935。它的优点是生态特别成熟推流端不管是用 OBS 还是 FFmpeg都能很方便地把音视频数据推到流媒体服务器上。缺点是延迟比较高通常在 2 到 5 秒左右而且浏览器原生不支持 RTMP用户要在网页里看 RTMP 流必须依赖 Flash 插件或者服务端转封装。虽然 Flash 已经退出历史舞台但 RTMP 作为“推流侧协议”依然很常用。你手里的大量直播流、存量系统、硬件编码器可能都还在走 RTMP 推流。1.2 WebRTC 是什么WebRTC 全称 Web Real-Time Communication也就是网页实时通信。它是一套由 Google 主导并开源的标准能力让浏览器之间可以不经插件直接进行音视频通话、数据传输。WebRTC 的传输层通常基于 UDP通过 SRTP 加密、NACK 重传、JitterBuffer 抖动缓冲等机制把端到端延迟压缩到 500 毫秒甚至更低。由于浏览器原生支持 WebRTC不需要安装任何插件所以它在在线教育、视频会议、远程医疗、低延迟直播等场景里越来越流行。WebRTC 的短板也明显一是没有统一的“拉流 URL”概念播放端需要经过信令协商、ICE 候选收集等流程才能建立连接二是对网络环境和服务器公网 IP 的依赖比较强稍不注意 candidate 配置错误页面就会一直处于 connecting 状态。1.3 为什么需要 RTMP 转 WebRTC现实中大量直播源、编码器、旧的推流端都支持 RTMP但用户更想在浏览器里直接用 WebRTC 低延迟观看。此时就需要一个“中间层”把 RTMP 流转换成 WebRTC 流这个中间层就是 rtmp2webrtc 转换的核心。如果去掉中间层常见做法是让客户端拉 HLS延迟基本在 5 到 15 秒适合点播但不适合互动直播。做实时连麦、互动答题、指挥调度、直播带货这类对延迟敏感的场景时延迟一高体验就会明显变差。所以“推流端保留 RTMP播放端走 WebRTC”成了一种性价比很高的组合。1.4 常见应用场景rtmp2webrtc 测试环境的常见应用场景包括验证现有 RTMP 直播源能否被低延迟播放。评估 WebRTC 在局域网内或公网下的播放效果。对比不同流媒体服务器的转协议能力和资源消耗。为产品提供低延迟播放能力做技术预研。在测试环境复现线上 WebRTC 播放失败问题便于排查。理解了背景之后接下来要明确一点我们并不是在自己的代码里实现私有转换算法而是借助成熟的开源流媒体服务器完成协议转换。2. 测试环境目标与整体架构2.1 测试环境要验证什么搭建 rtmp2webrtc 测试环境时重点不是“把服务跑起来”就结束而是要验证下面几件事RTMP 推流是否正常。流媒体服务器是否成功接收并转封装。WebRTC 播放是否能在浏览器中出画面。延迟大概处于什么水平。并发播放时服务器资源消耗是否可控。断流重推、播放端刷新是否影响其他观看端。如果当前只是为了做功能验证只要跑通“推流 - 转换 - 播放”链路即可。如果是为了生产选型则还需要叠加长时间稳定性、并发压力、弱网环境等测试。2.2 整体链路设计整个 rtmp2webrtc 测试链路可以用下面这张简图表示推流端(OBS/FFmpeg) --RTMP-- 流媒体服务器(SRS) --WebRTC-- 浏览器(Chrome/Edge)实际工作时推流端先通过 RTMP 协议将 H.264 AAC 音视频数据推送给流媒体服务器。流媒体服务器接收后把数据转封装成 WebRTC 需要的 RTP/SRTP 包并通过信令和 ICE 流程与浏览器建立连接。浏览器再通过 WebRTC 协议拉取视频画面。这里有一个容易混淆的点RTMP 推流和 WebRTC 播放并不要求使用同一个播放 URL。RTMP 地址通常是rtmp://ip/live/stream而 WebRTC 播放地址通常是webrtc://ip/live/stream或者通过 HTTP 页面触发播放。实际测试时这两个地址的流名要一致否则服务器找不到对应流。2.3 组件选型当前开源社区里支持 rtmp2webrtc 的常见方案有SRS国产开源流媒体服务器支持 RTMP、WebRTC、HLS、HTTP-FLV 等配置简单文档完善是很多团队的首选。ZLMediaKit基于 C 的高性能流媒体服务器支持 RTSP、RTMP、WebRTC、GB28181 等适合嵌入式设备和企业级项目。Janus一个通用 WebRTC 网关功能更偏 SFU 和音视频会议但也能接入 RTMP 流。Medooze面向 SFU 的流媒体服务器主要用在云会议场景。如果你是第一次搭 rtmp2webrtc 测试环境我更推荐先用 SRS因为它的 Docker 镜像体积小、启动快内置的 WebRTC 播放页面可以直接用来验证能省掉不少前端开发工作。本文的完整实战案例也以 SRS 为主。3. 环境准备与版本说明3.1 服务器要求rtmp2webrtc 测试环境不需要太高配置2 核 4G 的虚拟机或云主机就够跑通验证链路。操作系统可以选择 CentOS 7.9、Ubuntu 20.04/22.04也可以使用国产化操作系统如麒麟 V10只要内核支持 Docker 或主流 Linux 依赖库整体部署思路一致。需要特别注意的是 WebRTC 使用 UDP 传输因此要把相关的 UDP 端口在防火墙上放行。网络环境尽量让推流端、流媒体服务器、浏览器播放端处于同一个局域网内这样可以减少公网 NAT 带来的 candidate 问题。3.2 软件版本说明本文示例以 SRS 5.0 为例使用 Docker 方式启动。不同小版本的配置项可能略有差异如果你使用的是 SRS 4.0 或其他分支建议以对应版本的官方文档为主。Docker 和 FFmpeg 的安装命令也依赖你的操作系统发行版本实际使用时按当前环境调整即可。下面给出一个参考版本清单组件说明操作系统CentOS 7.9 / Ubuntu 22.04 / 麒麟 V10Docker20.10 及以上SRS5.0 系列FFmpeg4.4 及以上浏览器Chrome / Edge 最新版如果你的环境里 Docker 安装比较早建议先检查版本旧版本 Docker 可能影响 UDP 端口映射行为。3.3 网络与端口规划SRS 在 rtmp2webrtc 场景下主要涉及如下端口1935RTMP 推流端口。1985HTTP API 端口。8080HTTP 服务端口用来访问内置播放页面。8000/UDPWebRTC RTC 端口。真实生产环境中还需要考虑 8000 端口是否被占用以及云安全组是否放通了 TCP 和 UDP 规则。很多 WebRTC 播放失败的问题最后排查下来就是 UDP 端口不通。4. 基于 SRS 搭建 rtmp2webrtc 测试环境4.1 为什么选 SRSSRS 对 WebRTC 的支持比较成熟支持将 RTMP 流转封装为 WebRTC 流播放也支持 WebRTC 推流。它内置了rtc_player.html播放页面可以在浏览器里直接验证不用先写前端代码。SRS 还提供 HTTP API 查询流信息方便测试环境做自动化检查。最关键的是 SRS 采用单进程多协程模型内存占用不高部署方式简单很适合测试环境快速验证。即使你后续生产环境准备换成 ZLMediaKit也可以先用 SRS 验证整体链路是否可行。4.2 安装 Docker如果服务器上没有 Docker先安装 Docker。Ubuntu 和 CentOS 的安装命令不同这里以两种系统给出参考# Ubuntu / Debian 系列 sudo apt update sudo apt install -y docker.io docker-compose # CentOS 7 系列 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io安装完成后启动 Docker 服务sudo systemctl enable docker sudo systemctl start docker docker --version看到版本号输出后说明 Docker 安装成功。麒麟 V10 这类系统如果仓库里没有 Docker 包可以考虑使用清华源、阿里源等镜像仓库安装或者直接下载静态二进制包解压使用。这里不展开具体镜像源配置按你所在团队的安全策略来即可。4.3 启动 SRS 并开启 WebRTC先用最简单的默认配置启动 SRS验证镜像能否正常运行docker run --rm -it \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ -p 8000:8000/udp \ ossrs/srs:5这个命令会前台运行 SRS日志直接打到终端。看到类似下面的日志说明启动成功SRS 5.0.xxx Copyright (c) 2013-2024, The SRS Community ... rtmp server listen on 0.0.0.0:1935 http api listen on 0.0.0.0:1985 http server listen on 0.0.0.0:8080 rtc server listen on 0.0.0.0:8000默认配置下 WebRTC 不一定会按照你的网卡 IP 生成 candidate所以在实际测试环境中更推荐使用自定义配置文件。在服务器上创建srs.confmkdir -p /opt/srs/conf mkdir -p /opt/srs/objs vi /opt/srs/conf/srs.conf文件内容如下listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; listen 1985; } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } rtc_server { enabled on; listen 8000; # 重要改成你的服务器实际 IP否则 WebRTC 无法连接 candidate 192.168.1.100; }配置重点说明listen 1935指定 RTMP 监听端口。http_api开启 HTTP API后续可以用1985查询流信息。http_server开启 HTTP 静态文件服务用来访问播放页面。rtc_serverWebRTC 服务配置。candidate告诉浏览器“你要连接的媒体服务器地址是哪个”必须改成服务器实际可达的 IP。如果填错或保持默认浏览器会一直连接不上。然后通过 Docker 挂载配置文件启动docker run -d --name srs-rtc \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ -p 8000:8000/udp \ -v /opt/srs/conf/srs.conf:/usr/local/srs/conf/srs.conf \ -v /opt/srs/objs:/usr/local/srs/objs \ ossrs/srs:5这里挂载了配置文件目录方便后续调整候选 IP 或端口。4.4 验证服务状态容器启动后查看日志docker logs -f srs-rtc然后检查端口监听情况ss -lntup | grep -E 1935|1985|8080|8000如果 TCP 端口能正常监听说明 RTMP 和 HTTP 服务没问题。UDP 8000 端口也要能看到监听否则 WebRTC 服务没有成功启动。还可以通过 HTTP API 检查服务器状态curl http://127.0.0.1:1985/api/v1/versions返回的 JSON 里包含 SRS 版本信息说明 API 服务正常。4.5 使用 FFmpeg 模拟 RTMP 推流测试环境不一定有真实的摄像头或编码器可以用 FFmpeg 生成一段测试视频流并推到 SRS。先确保服务器或本机安装了 FFmpegffmpeg -version下面这条命令会生成一个 640x480、30 帧每秒的测试画面并叠加音频然后通过 RTMP 推流到 SRSffmpeg -f lavfi -re -i testsrcsize640x480:rate30 \ -f lavfi -re -i sinefrequency1000:sample_rate44100 \ -vcodec libx264 -preset veryfast -tune zerolatency \ -acodec aac \ -f flv rtmp://192.168.1.100:1935/live/livestream参数说明-f lavfi -i testsrc生成测试视频源。-f lavfi -i sine生成正弦波音频。-vcodec libx264使用 H.264 编码。-tune zerolatency降低编码延迟适合低延迟调试。-f flv rtmp://...以 FLV 封装格式推送到 RTMP 地址。推流后浏览器播放端才能看到画面。如果你有真实摄像头也可以直接用 OBS 推流设置里填rtmp://192.168.1.100:1935/live/livestream流密钥填写livestream即可。4.6 浏览器 WebRTC 播放验证SRS 内置了 WebRTC 播放页面可以通过下面的地址访问http://192.168.1.100:8080/players/rtc_player.html打开页面后在播放地址里填webrtc://192.168.1.100/live/livestream点击播放按钮稍等片刻就能看到 FFmpeg 生成的测试画面。这里有一个容易混淆的点WebRTC 播放地址的格式是webrtc://ip/live/livestream后面不需要再次带1935端口。SRS 会根据配置自动处理 WebRTC 连接。如果页面一直显示 connecting优先检查以下几点srs.conf中candidate是否填了正确的服务器 IP。UDP 8000 端口是否被防火墙拦截。浏览器是否限制了 UDP 传输。服务端日志是否提示 RTC 连接失败。浏览器播放成功后可以观察一下延迟情况。对着画面同步调整推流端时钟或播放计时器理论上 WebRTC 播放延迟远低于 RTMP/HLS 播放。4.7 验证流状态SRS 提供了 HTTP API 查看当前流列表可以用来确认这条 rtmp2webrtc 链路是否真的打通curl http://127.0.0.1:1985/api/v1/streams/返回 JSON 中会显示当前活跃流的app、name、url等信息。如果能看到类似的流信息说明 RTMP 推流端、SRS、WebRTC 播放端之间的数据通路是完整的。5. 备选方案ZLMediaKit 简介SRS 验证完整体链路后有些团队可能还会评估 ZLMediaKit因为它在 GB28181、RTSP、WebRTC 等场景里也很有优势。ZLMediaKit 的部署比 SRS 略微复杂一般需要从源码编译或使用第三方构建产物。ZLMediaKit 的 WebRTC 支持同样是基于原生 WebRTC 网关默认使用的是 10000 端口范围作为 RTC 端口。配置时重点确认rtc.port范围、服务器外网 IP 映射、SSL 证书等参数。如果你只是想验证流媒体服务器能否把 RTMP 转成 WebRTCSRS 是最快的路径如果你想做更复杂的多协议融合、设备接入ZLMediaKit 可以作为第二阶段评估对象。6. 常见问题与排查思路rtmp2webrtc 测试环境常见问题主要集中在网络、candidate、防火墙和浏览器兼容性上。下面整理成一张排查表问题现象常见原因解决思路WebRTC 页面一直 connectingcandidate 配置错误修改rtc_server.candidate为服务器实际 IP推流成功但播放黑屏编码格式或参数兼容问题使用 H.264 AAC避免使用浏览器不支持的编码WebRTC 页面打开就报错访问地址是公网但未走 HTTPS公网环境需要配置 HTTPSlocalhost 推荐用 HTTP播放延迟依然很高推流端视频编码参数未优化增加-tune zerolatency降低 GOP 大小UDP 端口无法连接云安全组未放行 UDP开放 8000/UDP 端口测试环境可临时关闭防火墙验证多个播放端互相影响服务器带宽或连接数不足检查 CPU、带宽和 SRS 连接数日志FFmpeg 推流中断网络不稳定或编码参数不合理降低码率、增大缓冲区、检查网络丢包如果遇到 WebRTC 连接失败可以在 Linux 服务器上用tcpdump抓包确认 UDP 包是否到达服务器tcpdump -i eth0 udp port 8000 -n如果在播放期间看不到 UDP 包进入服务器说明网络路径不通优先排查安全组、防火墙和路由。浏览器层面WebRTC 播放对 HTTPS 有严格限制。在公网测试时如果访问的是 HTTPS 页面页面里的 WebRTC 连接也必须使用 HTTPS 或 localhost 白名单。测试环境如果搭建在云主机上建议先用http://IP访问验证后续要生产化再补 HTTPS。还有一个常见坑是服务器有多个网卡。candidate 如果填错网卡 IP浏览器能把信令发给 SRS但媒体流到不了浏览器。你可以通过ip addr查看服务器所有网卡 IP选择浏览器真正能访问到的那个地址。7. 测试环境最佳实践与工程建议7.1 保持版本一致性rtmp2webrtc 测试环境从测试到生产最怕的就是版本漂移。SRS 4.0 和 5.0 的 WebRTC 配置项不同FFmpeg 4.x 和 5.x 的编码器行为也有差异。建议把镜像版本、配置文件、推流命令都记录到项目文档中方便后续复现。测试环境建议锁定 SRS 镜像版本例如ossrs/srs:5.0.128避免每次拉取最新镜像导致行为变化。等选型确定后再统一升级生产环境版本。7.2 网络配置要单独整理WebRTC 对 UDP 依赖很强测试环境的网络配置不能只靠“不用管”。建议单独记录服务器公网 IP / 内网 IP。candidate 最终填的是什么。防火墙规则、云安全组规则。浏览器访问使用的是 HTTP 还是 HTTPS。服务器到浏览器之间是否有 NAT 或负载均衡。这些信息最容易复现问题也最容易遗漏。之前遇到过一次 WebRTC 播放失败排查两小时后发现是安全组只放行了 TCP 端口UDP 8000 被漏掉了。7.3 建立自动化验证脚本手动推流、播放验证只是第一步。如果这个测试环境要被团队反复使用建议写一个自动化验证脚本至少完成检查 SRS 容器是否存活。检查 1935、1985、8080、8000 端口是否监听。用 FFmpeg 推流 10 秒。调用 API 验证流是否存在。清理推流进程。下面是一个简单的脚本示例#!/bin/bash SRS_IP192.168.1.100 SRS_PORT1935 SRS_API192.168.1.100:1985 echo 1. 检查 SRS 容器 docker ps | grep srs-rtc || echo 容器未运行 echo 2. 检查端口 ss -lntup | grep -E 1935|1985|8080|8000 echo 3. 推流 10 秒 timeout 10 ffmpeg -f lavfi -re -i testsrcsize320x240:rate15 \ -vcodec libx264 -preset ultrafast -tune zerolatency \ -f flv rtmp://${SRS_IP}:${SRS_PORT}/live/livestream echo 4. 查询流状态 curl -s http://${SRS_API}/api/v1/streams/ | grep livestream || echo 未查到流脚本不追求复杂重点是让每个验证步骤可重复、可输出、可交给 CI 使用。7.4 日志与监控SRS 启动时如果使用daemon off; srs_log_tank console;日志会输出到 Docker 标准输出。可以用docker logs查看。如果想持久化日志可以让 Docker 日志驱动对接文件或者把容器日志接入团队日志平台。测试期间建议重点记录推流开始和结束时间。WebRTC 连接建立时间。播放端是否出现丢包。服务器 CPU、内存、带宽占用。这些数据在做不同流媒体服务器对比时特别有用。7.5 安全边界测试环境虽然不直接面对生产用户但也要注意安全。SRS 的 HTTP API 可以查询和操作流信息如果暴露到公网存在被恶意调用风险。建议测试环境只开放必要的端口到内网或者限制来源 IP。如果业务最终要对外开放 WebRTC 播放建议在前端套一层 HTTPS并在流媒体服务器外层增加鉴权逻辑。不要直接暴露裸 API 到公网。另外FFmpeg 推流测试时生成的是合成视频流不涉及真实用户数据。如果要使用真实视频源需要注意隐私和数据合规要求避免将敏感画面传到测试环境。7.6 国产化操作系统适配注意部分团队的测试环境会部署在麒麟 V10 等国产化操作系统上。这类系统底层通常是 Linux 内核Docker 和 FFmpeg 的部署思路与 CentOS 基本一致。需要特别注意两点第一国产化系统的软件源可能不像 CentOS/Ubuntu 那么通用安装 Docker、FFmpeg 时可能遇到包缺失或源不可用的问题建议提前准备好离线安装包或镜像仓库代理。第二防火墙管理工具可能不是firewalld而是iptables或者厂商自研安全组件。配置 UDP 放行时要先确认使用哪种工具不要照搬 CentOS 文档。整体上先在内网测试机验证 Docker 可用性再进入 rtmp2webrtc 链路调试可以减少很多环境类问题。8. 总结与下一步到这里你已经掌握了一条完整的 rtmp2webrtc 测试环境搭建路径从 RTMP 与 WebRTC 的概念差异到 SRS 的 Docker 启动、自定义配置、FFmpeg 推流、浏览器 WebRTC 播放再到常见问题的排查思路。如果你用本文的配置顺利跑通了第一条 WebRTC 播放链路下一步可以继续研究三件事一是 SRS 的 HTTPS/WSS 配置让公网环境下播放更稳定二是用 ZLMediaKit 做多协议对比测试评估不同流媒体服务器的资源占用三是设计并发播放压测脚本用不同路数和码率测试服务器的承载能力。无论你的最终目标是直播低延迟方案选型还是给现有 RTMP 业务增加 WebRTC 播放能力先把测试环境的链路跑通、把 candidate 和 UDP 端口这类基础问题摸清楚后面真正做生产架构时就会顺利很多。

相关新闻