ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WebRTC转RTMP测试环境搭建:基于SRS的完整闭环实践

WebRTC转RTMP测试环境搭建:基于SRS的完整闭环实践 WebRTC 推流与 RTMP 拉流之间的协议转换是直播项目里经常要验证的一块。WebRTC 使用 UDP 传输天然适合低时延互动场景RTMP 基于 TCP 长连接兼容大量播放器和 CDN 分发链路。两者要打通不能靠客户端自己完成而是需要一台媒体服务器接收 WebRTC 媒体流再重新封装成 RTMP 输出。webrtc2rtmp 测试环境就是指在本地或内网准备一套最小系统把“WebRTC 推流 - 服务器转协议 - RTMP 播放”的完整链路跑通并确认音视频、延迟和日志都符合预期。本文以开源媒体服务器 SRS 为例从环境准备、配置编写、最小闭环、验证方法到常见问题排查完整搭建这套测试环境。如果你正在做 WebRTC 低时延直播、在线教育、连麦转推 CDN或者只是想搞清楚两个协议之间的转换过程这篇文章可以直接照着操作。1. 先理清 WebRTC 到 RTMP 的转换链路1.1 WebRTC 和 RTMP 为什么需要互相转换WebRTC 的核心目标是实时通信。浏览器或客户端通过 ICE 完成连接协商用 DTLS 做密钥交换再用 SRTP 传输音视频数据。整个过程基于 UDP支持丢包重传、前向纠错和拥塞控制因此延迟可以做到很低。但 WebRTC 的媒体流不是面向 CDN 分发设计的传统播放器、直播平台、监控大屏很难直接消费。RTMP 是 Adobe 定义的流媒体协议使用 TCP 长连接通过 AMF 封装信令消息通过 FLV Tag 封装音视频数据。它的优点是推流、拉流、转推生态成熟几乎所有直播平台和播放器都支持 RTMP 地址。缺点也很明显TCP 重传带来的延迟放大加上播放器缓冲策略端到端延迟通常高于 WebRTC。在实际直播系统中经常出现这样的组合主播使用浏览器 WebRTC 推流以获得更低的采集到服务器延迟服务器把流转成 RTMP 后再分发给 CDN、传统播放器或第三方直播平台。webrtc2rtmp 测试环境就是为这条组合链路准备的验证平台。1.2 测试环境需要验证哪些能力搭建 webrtc2rtmp 测试环境不只是“能推流、能拉流”这么简单。一个合格的测试环境至少要验证以下几个方面浏览器或 WebRTC 客户端能否成功发起推流包括信令协商、媒体传输、音视频轨道上报。媒体服务器能否同时监听 WebRTC 和 RTMP 两个协议栈并在内部完成协议转换。RTMP 播放器能否以可接受的延迟拉到流音画是否同步是否花屏或卡顿。服务器日志和 API 是否反映了完整的推流状态方便后续排错。在弱网、并发、低端设备等场景下链路是否仍然可用。这些能力对应不同的测试方法。最常见的做法是先把最小闭环跑通再逐步加入跨网段、弱网模拟和并发压力最后才考虑生产化部署。1.3 一条完整的测试链路长什么样以 SRS 作为媒体服务器测试链路可以描述为WebRTC 推流端浏览器 | | webrtc://server-ip/live/livestream v SRS 媒体服务器 |- 接收 WebRTC 媒体流 |- rtc_to_rtmp 协议转换 |- 通过 RTMP 端口输出 | | rtmp://server-ip/live/livestream v RTMP 播放器ffplay / VLC / OpenCV这条链路的关键点是推流路径和拉流路径必须指向同一个 vhost、app 和 stream。SRS 内部通过 app 和 stream 把 WebRTC 流和 RTMP 流关联起来。默认配置下推流使用webrtc://ip/live/livestream拉流使用rtmp://ip/live/livestream后面的/live/livestream就是关联键。2. 测试环境规划与依赖准备2.1 操作系统与硬件规划webrtc2rtmp 测试环境对硬件要求不高常规 Linux 虚拟机就可以跑通。推荐使用 Ubuntu 20.04、22.04、CentOS 7/8或者其他兼容 glibc 的 Linux 发行版。在国产化环境下麒麟操作系统 V10 也能编译运行 SRS但要注意编译工具链和依赖库版本可能较旧需要先补齐 gcc、make、pkg-config、openssl 开发包。硬件方面单路测试时 2 核 CPU、2 GB 内存即可。如果需要在浏览器端和播放端同时验证建议 4 核 4 GB 以上避免本机同时跑服务器、浏览器、ffmpeg 时资源不足影响测试结论。网络方面WebRTC 使用 UDPRTMP 使用 TCP。如果是在同一台机器测试只需要注意端口不冲突。如果 WebRTC 推流端和媒体服务器不在同一网段要提前确认网络是否能互通并检查安全组防火墙。2.2 端口规划与网络放行SRS 在 webrtc2rtmp 场景下至少需要四个端口。整理成表格如下端口协议服务作用1935TCPRTMP接收和输出 RTMP 流1985TCPHTTP API查询流信息、WebRTC 信令协商8080TCPHTTP Server提供网页播放器和静态文件8000UDPWebRTC传输 WebRTC 媒体数据在云服务器或启用了防火墙的机器上需要同时放行 TCP 和 UDP 端口。以 CentOS/RHEL 系列为例sudo firewall-cmd --add-port1935/tcp --permanent sudo firewall-cmd --add-port1985/tcp --permanent sudo firewall-cmd --add-port8080/tcp --permanent sudo firewall-cmd --add-port8000/udp --permanent sudo firewall-cmd --reload如果是云安全组除了操作系统防火墙还要在云控制台的安全组规则里放行相同端口。很多 WebRTC 推流失败都是因为只放行了 TCP忘记放行 UDP 8000导致 RTMP 能访问但 WebRTC 信令和媒体一直无法建立。2.3 编译依赖安装SRS 提供源码编译方式先安装编译工具和依赖库。Ubuntu/Debian 系统sudo apt update sudo apt install -y git gcc make pkg-config openssl libssl-dev ffmpegCentOS/RHEL 系统sudo yum install -y git gcc make pkg-config openssl openssl-devel ffmpegffmpeg 不是编译 SRS 的必需依赖但强烈建议安装。后面验证 RTMP 拉流、查看流信息、扩展转推链路时都要用到 ffmpeg 和 ffplay。麒麟 V10 等国产化系统如果包含独立的软件源优先使用系统自带的安装命令补齐依赖。如果缺少某个依赖包可以先执行yum provides或apt search查找对应包名确认版本后再安装不建议直接跳过。2.4 下载并编译 SRSSRS 的源码托管在 GitHub使用 git 拉取稳定分支即可。不同版本对配置项的支持有差异建议使用官方 release 或对应稳定分支。以常见方式为例git clone https://github.com/ossrs/srs.git cd srs/trunk ./configure --full make -j4--full会编译 SRS 的全部模块包括 RTMP、WebRTC、HTTP、HLS、DVR、转封装等。测试环境直接使用完整编译可以减少后续启用功能时重新编译的麻烦。编译完成后检查版本./objs/srs -v如果命令能输出 SRS 版本信息说明编译成功。编译过程中如果出现缺少pkg-config、找不到 OpenSSL 头文件等错误先回到上一节补齐依赖再重新执行./configure和make不要直接忽略错误继续运行。3. 配置 WebRTC 与 RTMP 双协议输出3.1 一份同时开启 WebRTC 和 RTMP 的配置文件SRS 默认配置放在conf/srs.conf可以基于它修改也可以新建独立配置文件。下面的示例把核心项显式列出便于测试时对照理解# conf/webrtc2rtmp.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; # candidate 192.168.1.10; } vhost __defaultVhost__ { rtc { enabled on; rtmp_to_rtc on; rtc_to_rtmp on; } }这段配置里listen 1935用于 RTMPrtc_server.listen 8000用于 WebRTChttp_api提供 HTTP 接口http_server提供网页访问能力。关键开关在vhost内的rtc配置块。rtc_to_rtmp on表示允许 WebRTC 流转换成 RTMP 输出这是 webrtc2rtmp 场景的核心配置。rtmp_to_rtc on则是反向转换开关如果后续要测试 RTMP 推流后 WebRTC 播放也会用到。3.2 candidate 与多网卡问题WebRTC 连接过程中服务器需要向客户端提供候选地址告诉浏览器往哪个 IP 和端口发送媒体数据。SRS 在只有一个网卡的内网环境里通常能自动探测到正确地址但在云服务器、多网卡、NAT 环境下自动探测可能选错 IP。当遇到浏览器与服务器之间始终连接不上、推流一直处于协商状态时优先检查 SRS 启动日志里的 candidate 地址。如果地址不是客户端能访问的 IP就需要在rtc_server配置块里显式指定rtc_server { enabled on; listen 8000; candidate 192.168.1.10; }这里的192.168.1.10要替换成客户端实际可以访问的服务器 IP。测试环境如果推流端和服务器在同一个局域网直接填服务器内网 IP 即可。如果客户端通过公网访问需要填公网 IP并在防火墙上放行对应 UDP 端口。3.3 启动 SRS 并检查日志使用自定义配置启动 SRS./objs/srs -c conf/webrtc2rtmp.conf因为配置了daemon off和srs_log_tank console日志会直接输出到终端。启动成功时终端会出现类似下面的信息RTMP listen at :1935 HTTP API listen at :1985 HTTP Server listen at :8080 WebRTC listen at :8000启动后另开一个终端检查端口监听状态ss -tulnp | grep -E :1935|:1985|:8080|:8000确认四个端口都在监听后再通过 HTTP API 查看服务状态curl -s http://127.0.0.1:1985/api/v1/versions如果返回包含 SRS 版本号的 JSON说明 HTTP API 正常工作。这一步通过后才进入推流和拉流验证。4. 搭建最小闭环WebRTC 推流到 RTMP 拉流4.1 使用浏览器完成 WebRTC 推流SRS 编译后带有演示页面可以通过 HTTP 端口访问。不同版本页面路径略有不同一般会提供播放器页面用于 WebRTC 推流和播放、RTMP 播放等测试。先通过浏览器访问http://服务器IP:8080找到 WebRTC 推流入口输入推流地址webrtc://服务器IP/live/livestream页面中的 WebRTC 推流逻辑一般包括以下步骤调用getUserMedia获取摄像头和麦克风。创建RTCPeerConnection并添加音视频轨道。通过 SRS 的 HTTP API 与服务器交换 SDP。完成 DTLS 握手后浏览器开始向服务器发送 SRTP 媒体数据。如果没有合适的演示页面也可以写一个简单的 HTML 页面来理解推流过程。完整的 SRS WebRTC 推流页面需要处理 SDP 交换生产项目通常使用官方 SDK 或成熟前端库这里只给出页面结构video idlocal autoplay muted playsinline/video button idbtn开始推流/button script // 思路获取本地媒体 - 创建 RTCPeerConnection - 添加音视频轨道 // - 向 SRS HTTP API 请求推流地址并交换 SDP。 // 不同版本 SRS 的 API 路径有差异建议先使用官方示例页面。 /script浏览器推流成功时页面上通常会出现“推流中”状态本地视频画面也会显示。此时不要马上关闭页面先保持推流状态再去另一终端验证 RTMP 拉流这样才能确认转换链路是完整的。4.2 使用 ffplay 拉取 RTMP 流在另一台机器或本机终端执行 ffplay 拉流ffplay -fflags nobuffer -flags low_delay -framedrop -i rtmp://服务器IP/live/livestream命令中的参数含义如下-fflags nobuffer减少播放器缓冲降低延迟。-flags low_delay通知解码器优先使用低延迟模式。-framedrop在 CPU 解码不及时的时候允许丢帧避免音画延迟越来越大。-i指定 RTMP 地址。如果画面和声音都能出来说明 SRS 已经成功把 WebRTC 流转成了 RTMP 流webrtc2rtmp 的最小闭环跑通。这里要注意推流 URL 和拉流 URL 中的 app 和 stream 必须一致。如果推流到live/livestream拉流却写live/testSRS 会认为这是不同的一路流播放端自然没数据。4.3 使用 ffprobe 验证流信息ffplay 能播放只能说明链路通了但无法精确判断编码参数。使用 ffprobe 查看流详情ffprobe -show_streams -show_format rtmp://服务器IP/live/livestream输出中重点关注视频编码格式是否 H.264分辨率、帧率是否符合预期。音频编码格式是否 AAC采样率、声道数是否正确。format 部分中的 duration、bitrate 是否持续增长。如果音频或视频缺失说明 WebRTC 推流端可能只发布了一个轨道或者浏览器没有正确授权麦克风摄像头。此时回到浏览器页面检查授权状态再对比 ffprobe 输出。4.4 用 ffmpeg 扩展测试链路有些场景需要验证“SRS 转出的 RTMP 流能否再次被转推”。比如把 SRS 的输出转发到另一个流媒体服务器或 CDN。使用 ffmpeg 拉流然后转推ffmpeg -i rtmp://服务器IP/live/livestream -c copy -f flv rtmp://目标服务器/app/stream-c copy表示不重新编码只做封装转换。这种方式对服务器 CPU 压力很小适合在测试环境验证转推链路。如果目标服务器需要变更编码格式再考虑去掉-c copy改为指定编码器。这里要注意转推失败不一定都是 SRS 的问题。常见原因是目标 RTMP 地址对 app、stream 名称有限制或者目标服务器拒绝来自非白名单 IP 的推流。排查时先确认目标地址用其他工具能否直接推流成功。5. 关键参数与配置项说明5.1 rtc_server 核心参数rtc_server配置块控制 WebRTC 服务行为常用参数如下参数作用默认说明enabled是否开启 WebRTC 服务on / offlistenWebRTC 媒体监听端口默认 8000candidate对外宣告的候选 IP自动探测可能出错多网卡时建议手动指定reuse_port是否允许多个 worker 复用 UDP 端口生产环境多进程场景使用candidate是最容易踩坑的参数。自动探测在单网卡测试环境通常没问题但一旦服务器有多个网卡、虚拟网卡或者处于 NAT 后面自动探测出的地址可能无法被客户端访问表现为浏览器一直连接中。5.2 vhost 内 rtc 参数vhost内的rtc配置块控制协议转换行为。在 SRS 5.0 及之后版本中常见的配置项如下vhost __defaultVhost__ { rtc { enabled on; rtmp_to_rtc on; rtc_to_rtmp on; } }参数说明enabled是否在该 vhost 上开启 WebRTC 支持。rtmp_to_rtc是否允许 RTMP 推流转换成 WebRTC 播放流。rtc_to_rtmp是否允许 WebRTC 推流转换成 RTMP 播放流。这是 webrtc2rtmp 测试环境的核心开关。如果rtc_to_rtmp为 off即使 WebRTC 推流正常RTMP 播放端也会拉不到流。5.3 http_api 与 http_server 的作用HTTP API 和 HTTP Server 看起来都走 HTTP 协议作用完全不同。HTTP API 面向接口调用用于 WebRTC 信令协商和流状态查询。WebRTC 推流页面需要通过 HTTP API 获取服务器 SDP完成信令交互。排错时也经常通过这个接口查询在线流。HTTP Server 面向静态资源用于存放网页播放器、播放页面等文件。内网测试时可以直接通过浏览器访问 8080 端口打开 SRS 自带的 Web 测试页面避免本地再搭一套静态文件服务。5.4 测试环境与生产环境的参数差异测试环境追求快速跑通配置可以尽量简化生产环境需要把对外暴露地址、防火墙策略、日志持久化、权限都考虑进去。两者的差异在下表体现维度测试环境生产环境部署规模单实例多实例、集群、负载均衡candidate可不配或用内网 IP必须配置公网可达候选地址访问协议内网 HTTP 访问域名、HTTPS、WebRTC 安全上下文防火墙开发机放行端口即可安全组和本机防火墙最小化放行日志控制台输出落盘、集中采集、告警鉴权不开启需要推流鉴权、播放防盗链监控人工查看连接数、码率、丢包率、延迟监控回滚重启进程即可版本化配置、灰度发布6. 验证结果解读与延迟分析6.1 通过 HTTP API 查看在线流推流过程中查询当前 SRS 上的在线流curl -s http://127.0.0.1:1985/api/v1/streams | head -c 2000正常时返回 JSON 中会包含推流信息。输出结构类似{ streams: [ { app: live, name: livestream, vhost: __defaultVhost__, url: rtmp://192.168.1.10/live/livestream } ] }字段含义app应用名。name流名。vhost虚拟主机。urlSRS 感知到的当前推流地址。这里的 URL 虽然显示成 RTMP 地址但流来源可能是 WebRTC 推流。SRS 在内部把 WebRTC 流和 RTMP 播放地址关联起来所以 API 显示为 RTMP 形式便于其他模块理解。6.2 延迟从哪里产生WebRTC 推流端的采集、编码、网络传输本身延迟很低但转换为 RTMP 后延迟会明显增加。原因主要有三个SRS 做协议转换时需要把 RTP 数据包重新封装成 FLV Tag这个过程会产生一定缓冲。RTMP 基于 TCP 传输网络抖动时 TCP 重传会放大延迟。播放器为了播放平滑会在本地设置缓冲ffplay 默认缓冲较大VLC 类似。测试环境下RTMP 端看到 1 到 5 秒延迟属于常见情况。如果使用 ffplay 加低延迟参数延迟可以更接近 1 秒左右。不要用 RTMP 播放端的延迟直接评价 WebRTC 转协议的硬件性能两者不是同一层级的指标。6.3 如何判断测试是否通过判断 webrtc2rtmp 测试环境是否合格可以使用以下检查点浏览器推流页面显示推流成功没有长时间连接中。ffplay 能拉到画面和声音没有花屏和长时间卡顿。ffprobe 输出包含预期的视频编码、分辨率、帧率、音频编码和声道信息。HTTP API 能查询到该路流且推流结束或浏览器关闭后流信息随之消失。SRS 日志中没有持续的丢包、解码失败、DTLS 握手失败等异常。以上检查点都通过说明测试环境具备继续开展弱网、并发和功能扩展测试的基础。7. 常见问题与排查路径7.1 浏览器无法推流或没有画面现象点击推流后页面一直提示连接中或者推流成功但 ffplay 拉不到画面。可能原因浏览器没有摄像头或麦克风权限。浏览器不支持当前编码格式例如某些浏览器默认不支持 H.264 推流。SRS 配置中rtc_server未开启或 UDP 8000 端口防火墙未放行。candidate 地址不可达。排查顺序检查浏览器 console 是否有权限错误或 SDP 相关报错。打开 SRS 终端日志看是否出现 WebRTC 协商请求。确认 UDP 8000 端口在防火墙中已放行。确认推流 URL 的 app 和 stream 与后续拉流一致。推荐做法使用 Chrome 或 Edge 测试优先开启摄像头权限并将页面通过 HTTPS 或 localhost 访问。如果 SRS 通过内网 IP 访问浏览器可能因为安全上下文限制拒绝摄像头需要单独处理。7.2 SRS 启动时报 UDP 端口绑定失败现象启动时提示 bind UDP port failed 或者 address already in use。可能原因8000 端口已被其他进程占用。之前启动过多个 SRS 实例旧进程没有退出。处理方式ss -unlp | grep 8000找到占用进程后停止冲突进程。如果希望在同一台机器运行多个 SRS 实例需要为每个实例配置不同的rtc_server.listen端口并同步调整防火墙放行策略。7.3 跨网段推流时黑屏或连接中现象浏览器和服务器在同一个网段时推流正常但客户端切换到其他网段后一直连接中。可能原因SRS 在rtc_server配置中没有指定 candidate自动探测出的 IP 是服务器内网地址客户端无法访问。处理方式在rtc_server配置中显式指定客户端可访问的 IPrtc_server { enabled on; listen 8000; candidate 公网IP或互通网段IP; }修改后重启 SRS并再次检查日志中输出的 candidate 是否已经变成配置的地址。7.4 RTMP 拉流 Connection refused现象ffplay 连接 RTMP 地址时直接提示 Connection refused。可能原因SRS 未启动。RTMP 端口 1935 没有被监听。防火墙阻断了 TCP 1935。排查顺序ss -tlnp | grep 1935 telnet 服务器IP 1935如果端口未监听检查 SRS 进程和日志。如果端口已监听但连接失败检查防火墙安全组是否放行。云服务器还要确认安全组规则是否同时针对入站和出站做好了配置。7.5 OpenCV 打开 RTMP 失败现象使用 OpenCV 的 VideoCapture 拉取 RTMP 流时返回的cap.isOpened()为 False。可能原因OpenCV 编译时没有启用 FFmpeg 后端。RTMP 地址本身不可用或者流名写错。RTMP URL 中带鉴权参数参数没有正确编码。先用 ffprobe 确认地址可用ffprobe rtmp://服务器IP/live/livestream如果 ffprobe 能读到流说明地址没问题问题在 OpenCV 的构建配置。检查 OpenCV 编译信息import cv2 print(cv2.getBuildInformation())输出中查找 FFmpeg 部分如果显示为 NO需要安装带 FFmpeg 支持的 OpenCV 版本或者改用 ffmpeg 命令行、PyAV 等方式读取。7.6 弱网卡顿怎么测试和优化测试环境建议用 Linux 的 tc 命令模拟网络丢包、延迟和抖动。以网卡 eth0 为例sudo tc qdisc add dev eth0 root netem delay 100ms loss 5%模拟完成后用同一路 WebRTC 推流执行弱网测试观察浏览器页面和 RTMP 播放端的变化。测试结束后必须清除规则sudo tc qdisc del dev eth0 root弱网下观察重点WebRTC 推流端是否会自行降低码率或分辨率。RTMP 播放端是否出现长时间卡顿卡顿是否可恢复。SRS 日志是否出现丢包、超时、连接断开。优化方向可以从几个层面入手WebRTC 推流端使用 H.264 编码并开启码率自适应SRS 侧关注 UDP 缓冲区大小和服务负载播放端采用更灵活的缓冲策略必要时降级到 HLS。测试环境里的优化结论要放到真实网络条件下再验证一遍不要直接照搬参数。8. 从测试环境走向生产环境8.1 测试环境与生产环境的主要差异测试环境的目的是快速暴露链路问题生产环境则需要长时间稳定运行。除了前面提到的参数差异生产环境还要额外考虑数据落盘、监控告警、权限控制和集群横向扩展。SRS 单实例在测试环境足够但生产环境如果承载高并发直播需要考虑多实例部署、源站与边缘节点分离、负载均衡策略。WebRTC 使用 UDP 传输负载均衡不能简单按 TCP 连接分发需要结合流媒体服务的特点设计路由策略。日志管理也和生产运维直接相关。测试环境可以直接看终端日志生产环境建议把 SRS 日志落到独立磁盘按天滚动并接入集中日志平台。这样出现推流失败或转换异常时可以按照时间线检索日志而不是登录服务器翻文件。8.2 环境检查清单在发布或交付前可以按下面的清单逐项确认编译依赖是否完整SRS 是否能正常输出版本信息。1935、1985、8080、8000 四个端口是否都在监听。防火墙和安全组是否同时放行 TCP 和 UDP 端口。candidate 地址是否设置为客户端可访问的 IP。使用同一个 app 和 stream 完成 WebRTC 推流和 RTMP 拉流验证。ffprobe 输出是否包含视频和音频编码是否符合预期。推流结束后HTTP API 是否能看到流信息消失。多网卡环境下日志中的 candidate 是否指向正确网卡。跨网段测试时RTMP 播放端是否仍然可以正常拉流。弱网测试结束后tc 规则是否已清除。8.3 后续扩展方向webrtc2rtmp 测试环境跑通后可以继续扩展以下方向反向链路测试配置rtmp_to_rtc on验证 RTMP 推流转 WebRTC 播放。多协议输出开启 HLS、HTTP-FLV同一路流同时提供给不同场景。录制与回放配置 DVR 模块把推流写入本地文件。鉴权与防盗链在 SRS 前面增加鉴权服务保护推流和拉流地址。集群部署把单 SRS 替换为源站加边缘的集群结构测试负载均衡和流分发。对新手来说最有价值的练习不是把页面点通而是故意把环境“弄坏”再按日志把问题找回来。比如改错端口、关掉防火墙、换一个不支持 H.264 的浏览器然后观察失败现象再用前面提供的排查清单逐步收敛。这样练过一遍之后再谈 webrtc2rtmp 的生产化部署会顺利很多。
返回列表