WebRTC-Streamer 教程:用浏览器播放 RTSP/RTMP/本地采集的实时流

RTC相关项目 精选 19 分钟 |
WebRTC-Streamer 教程:用浏览器播放 RTSP/RTMP/本地采集的实时流

WebRTC-Streamer 是一个非常实用的“小而强”的流媒体转发服务,可以把各种输入源(RTSP/RTMP/本地采集设备/屏幕捕获等)转成 WebRTC,在浏览器里实现低延迟播放。

  • WebRTC-Streamer 能做什么?适合哪些场景?
  • 如何通过命令行或 Docker 快速启动?
  • 如何把 RTSP 摄像头/本地采集设备转成浏览器可播放的 WebRTC?
  • 如何使用内置 STUN/TURN 解决 NAT/防火墙问题?
  • 如何将播放器嵌入你自己的网页(HTML、WebComponents、WHEP)?
  • 如何与 Janus/Jitsi 等现有 WebRTC 平台集成?
  • 如果要自己编译源码,需要准备哪些依赖?

1. WebRTC-Streamer 概览

1.1 项目简介

WebRTC-Streamer 的定位可以简单理解为:

把各种媒体源(RTSP/RTMP/文件/桌面捕获/本地采集等)转成 WebRTC,在浏览器中播放。

它本身集成了:

  • 内置 HTTP 服务器:默认 0.0.0.0:8000,用于提供 Demo 页面与 API;
  • WebRTC 媒体转发逻辑:负责拉取 RTSP/文件/采集设备等输入源,并通过 WebRTC 推给浏览器;
  • 可选嵌入式 STUN/TURN 服务:方便在 NAT 场景下直接内置穿透能力;
  • 多平台支持:Linux、Windows、macOS 都有构建流水线与发布包;
  • Docker 镜像:开箱即用,适合放在云服务器/容器平台中运行。

1.2 官方资源链接


2. 命令行使用与基础参数

官方 README 提供了详细的命令行使用说明,核心命令形如:

./webrtc-streamer [OPTION...] [urls...]

这里的 urls... 一般就是你要转发的媒体源(RTSP/RTMP/文件/桌面捕获等),而 OPTION 用于控制 HTTP/WebRTC/STUN/TURN 等行为。

2.1 通用选项

-h, --help        打印帮助
-V, --version     打印版本号
-v, --verbose     日志详细级别(可多次叠加 -v)
-C, --config arg  从 JSON 配置文件加载流列表
-n, --name arg    注册一个流的名称
-u, --video arg   为指定名称的流配置视频 URL
-U, --audio arg   为指定名称的流配置音频 URL

常见用法有两种:

  • 简单模式:直接在命令行后面拼 RTSP/RTMP/文件 URL;
  • 配置模式:把多个流写入一个 config.json,然后用 -C config.json 统一加载。

2.2 HTTP 服务器相关参数

-H, --http arg        HTTP 服务器绑定地址(默认 0.0.0.0:8000)
-w, --webroot arg     静态文件根目录路径
-c, --cert arg        HTTPS 私钥和证书路径
-N, --threads arg     HTTP 服务器线程数
-A, --passwd arg      HTTP 基础认证密码文件
-D, --domain arg      HTTP 认证域(默认:mydomain.com)
-X, --disable-xframe  关闭 X-Frame-Options 头
-B, --base-path arg   HTTP 服务的基础路径

实践中常见场景:

  • 只改端口:比如 -H 0.0.0.0:9000
  • 启用 HTTPS:提供 -c 指向包含私钥+证书的文件;
  • 访问控制:用 -A 配合密码文件限制访问,或利用 -D 调整认证域;
  • 嵌入到其它站点:有些情况下你需要允许 <iframe> 引用,此时可使用 -X 关闭默认的 X-Frame-Options 限制。

2.3 WebRTC 相关参数

-m, --maxpc arg         最大 PeerConnection 数量
-I, --ice-transport arg 配置 ICE 传输类型
-T, --turn-server arg   启动内置 TURN 服务器
-t, --turn arg          使用外部 TURN 中继
-S, --stun-server arg   启动内置 STUN 服务器
-s, --stun arg          使用外部 STUN 服务器
-R, --udp-range arg     WebRTC UDP 端口范围
-W, --trials arg        WebRTC 实验参数
-a, --audio-layer arg   指定音频采集层(留空则为 dummy)
-q, --publish-filter arg 发布过滤规则
-o, --null-codec        使用 "null" 编解码(直接透传压缩帧)
-b, --plan-b            使用 SDP plan-B(默认 unified plan)

其中几个关键点:

  • -S/--stun-server-T/--turn-server
    • 可以在同一进程中运行一个简易 STUN/TURN 服务器,适合内网实验或小规模部署;
  • -s/--stun-t/--turn
    • 指定外部 STUN/TURN 服务地址,例如指向你自建的 coturn;
  • -R/--udp-range
    • 限制 WebRTC 传输使用的 UDP 端口范围,方便配合防火墙规则;
  • -o/--null-codec
    • 不对视频帧进行重新编码,而是以 kNative 形式直接透传编码后的 H264 帧,CPU 开销低但功能受限(不支持缩放/带宽自适应等)。

2.4 媒体源 URL 类型

README 中列出了支持的 URL 方案,对应不同的采集方式:

  • rtsp://:通过 live555 作为 RTSP/MKV 捕获器;
  • file://:从文件(mkv 等)读取;
  • rmtp://:通过 librtmp 捕获 RTMP 源(;
  • screen://:桌面全屏捕获;
  • window://:窗口捕获;
  • v4l2://:Linux V4L2 设备捕获 H264 帧(Windows 不支持);
  • videocap://:本地视频采集设备;
  • audiocap://:本地音频采集设备;
  • 以及通过 -n name -u url 注册的别名流。

典型场景:把一台 RTSP 摄像头的画面推到浏览器,你只需要提供 rtsp:// URL 即可。

2.5 最小示例:从配置文件启动

./webrtc-streamer -C config.json
  • config.json 中写入多个流及其名称;
  • 浏览器端加载官方提供的 webrtcstreamer.html,通过 URL 选择流进行播放。

官方 Demo 链接(公开环境可能会随时间变化):


3. Docker 快速运行

对于生产或云端部署,使用 Docker 镜像是最简便的方式之一。

3.1 基础运行

docker run -p 8000:8000 -it mpromonet/webrtc-streamer
  • 容器内 WebRTC-Streamer 默认在 0.0.0.0:8000 提供 HTTP 服务;
  • 映射到宿主机 8000 端口后,即可通过浏览器访问 http://<宿主IP>:8000/

3.2 暴露宿主机摄像头(V4L2)

docker run --device=/dev/video0 -p 8000:8000 -it mpromonet/webrtc-streamer
  • 通过 --device=/dev/video0 将宿主机的 V4L2 采集设备映射进容器;
  • 之后在 WebRTC-Streamer 中使用 v4l2:// URL 即可访问该设备。

3.3 查看所有参数

docker run -p 8000:8000 -it mpromonet/webrtc-streamer --help

这会直接把 webrtc-streamer --help 的输出显示在终端里,便于你快速查阅最新版本的参数说明。

3.4 启动时注册 RTSP 流

docker run -p 8000:8000 -it \
  mpromonet/webrtc-streamer \
  -n raspicam -u rtsp://pi2.local:8554/unicast
  • 通过 -n raspicam 注册一个名为 raspicam 的流;
  • -u 指定该流对应的 RTSP URL;
  • 浏览器侧可以通过相应的流名进行播放。

3.5 挂载 config.json

docker run -p 8000:8000 \
  -v $PWD/config.json:/usr/local/share/webrtc-streamer/config.json \
  mpromonet/webrtc-streamer
  • 将本地 config.json 挂载到容器默认读取位置;
  • 启动时即可自动加载流配置。

3.6 使用 host 网络模式

docker run --net host mpromonet/webrtc-streamer
  • 容器直接共用宿主机网络命名空间;
  • 适用于需要访问本地多播网络、特殊端口映射或更复杂的 NAT 场景。

提示:生产中建议结合防火墙/反向代理明确控制暴露端口,而不是简单暴露所有接口。


4. 内置 STUN/TURN:NAT 场景部署

在复杂网络(NAT/防火墙)环境中,为了让浏览器顺利建立 WebRTC 连接,通常需要 STUN/TURN 服务。

WebRTC-Streamer 支持内置 STUN/TURN 服务器,可直接在同一进程中启动并使用,减少部署组件。

4.1 启动内置 STUN/TURN 示例

README 中给出了几种组合方式:

# 启动内置 STUN,外部客户端使用公网 IP 访问
./webrtc-streamer --stun-server=0.0.0.0:3478 --stun=$(curl -s ifconfig.me):3478

# 启动内置 TURN(仅 TURN)
./webrtc-streamer --stun=- --turn-server=0.0.0.0:3478 -tturn:turn@$(curl -s ifconfig.me):3478

# 同时启动内置 STUN + TURN
./webrtc-streamer \
  --stun-server=0.0.0.0:3478 --stun=$(curl -s ifconfig.me):3478 \
  --turn-server=0.0.0.0:3479 --turn=turn:turn@$(curl -s ifconfig.me):3479

其中:

  • --stun-server=0.0.0.0:3478:在本机 3478 端口监听 STUN 请求;
  • --stun=$(curl -s ifconfig.me):3478:把公网 IP + 端口告诉客户端使用;
  • --turn-server=0.0.0.0:3478:在本机开启 TURN 服务;
  • -tturn:turn@公网IP:端口:客户端使用的 TURN URL,包含用户名 turn 和密码 turn

说明:curl -s ifconfig.me 只是一个获取公网 IP 的简写,你也可以直接写死公网 IP。

4.2 配合 UPnP 自动映射端口

如果路由器支持 UPnP,可以用 upnpc 工具自动添加端口映射:

upnpc -r 8000 tcp 3478 tcp 3478 udp
  • 映射 HTTP 端口 8000(TCP);
  • 映射 STUN 端口 3478(TCP/UDP);
  • 你可以根据实际部署端口进行适配调整。

5. 将 WebRTC-Streamer 嵌入你自己的网页

WebRTC-Streamer 并不强制你使用它内置的 HTTP 页面,你可以:

  • 使用单独的 Web 服务器(Nginx/Node.js 等)提供前端;
  • 在前端中调用 WebRTC-Streamer 的 API,实现自定义 UI/交互;
  • 使用官方提供的 JS 库 webrtcstreamer.js 或 WebComponent 封装。

5.1 在自定义 HTML 中嵌入 WebRTC 播放

核心是创建一个 WebRtcStreamer 实例,并告诉它:

  • 要渲染到哪个 <video> 标签;
  • WebRTC-Streamer 的服务地址;
  • 要播放的流 URL(如 RTSP 地址)。

示例

<html>
<head>
  <script src="libs/adapter.min.js"></script>
  <script src="webrtcstreamer.js"></script>
  <script>
    // 页面加载完成后,连接到 webrtc-streamer 并拉取 RTSP 流
    var webRtcServer = null;
    window.onload = function () {
      webRtcServer = new WebRtcStreamer(
        "video",
        location.protocol + "//" + location.hostname + ":8000" // webrtc-streamer 地址
      );
      webRtcServer.connect(
        "rtsp://196.21.92.82/axis-media/media.amp",
        "",
        "rtptransport=tcp&timeout=60"
      );
    };
    window.onbeforeunload = function () {
      if (webRtcServer) webRtcServer.disconnect();
    };
  </script>
</head>
<body>
  <video id="video" muted playsinline></video>
</body>
</html>

你可以将该 HTML 放在任何 Web 服务器中,只要它能访问 WebRTC-Streamer 提供的 HTTP/WebRTC 服务即可。

5.2 使用 WebComponents 封装

WebRTC-Streamer 还提供了一个现成的自定义元素 <webrtc-streamer>,可以用更简洁的方式在 HTML 中嵌入播放:

<html>
<head>
  <script type="module" src="webrtc-streamer-element.js"></script>
</head>
<body>
  <!-- url 指向要播放的 RTSP 源 -->
  <webrtc-streamer url="rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"></webrtc-streamer>
</body>
</html>

官方还提供了:

  • 带流选择器的 WebComponent Demo;
  • 集成 Google Map 的 WebComponent Demo;

你可以参考仓库中的 HTML 示例,按需扩展自己的 UI。

5.3 使用 WHEP 协议播放

WebRTC-Streamer 支持草案标准 WHEP(WebRTC-HTTP Egress Protocol),方便与其他 WebRTC 播放器互通。

官方示例使用 Eyevinn 的 whep-video 组件:

<html>
<head>
  <script src="https://unpkg.com/@eyevinn/whep-video-component@latest/dist/whep-video.component.js"></script>
</head>
<body>
  <whep-video id="video" muted autoplay></whep-video>
  <script>
    // 通过 WHEP 播放 webrtc-streamer 提供的流
    video.setAttribute(
      "src",
      `${location.origin}/api/whep?url=Asahi&options=rtptransport%3dtcp%26timeout%3d60`
    );
  </script>
</body>
</html>

这里的 url=Asahi 表示要播放的流名称,options 则是转义后的连接参数。


6. 与 Janus/Jitsi 等 WebRTC 平台集成

如果你已有 Janus Gateway 或 Jitsi 等 WebRTC 平台,可以把 WebRTC-Streamer 作为“媒体源提供方”,再由这些平台做房间管理、多方会话等高级逻辑。

6.1 推流到 Janus 视频房间

官方封装了一个 JanusVideoRoom JS 工具,用来连接 Janus 视频房间,并使用 WebRTC-Streamer 作为发布端。

浏览器端简化示例:

<html>
<head>
  <script src="janusvideoroom.js"></script>
  <script>
    // 连接 Janus 视频房间,并把两个 RTSP 源推入房间
    var janus = new JanusVideoRoom("https://janus.conf.meetecho.com/janus", null);
    janus.join(1234, "rtsp://pi2.local:8554/unicast", "pi2");
    janus.join(1234, "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", "media");
  </script>
</head>
</html>
  • 1234 是房间 ID;
  • 后面的 RTSP URL 由 WebRTC-Streamer 拉取并发布;
  • "pi2""media" 是本地给出的标签。

也可以在 Node.js 里使用同样的 JS API,通过 then-request 等库在服务端完成同样的逻辑。

6.2 推流到 Jitsi 会议室

类似地,针对 Jitsi(基于 XMPP 协议),官方提供了 XMPPVideoRoom 工具:

<html>
<head>
  <script src="libs/strophe.min.js"></script>
  <script src="libs/strophe.muc.min.js"></script>
  <script src="libs/strophe.disco.min.js"></script>
  <script src="libs/strophe.jingle.sdp.js"></script>
  <script src="libs/jquery-3.5.1.min.js"></script>
  <script src="xmppvideoroom.js"></script>
  <script>
    // 将 RTSP 源作为 WebRTC 流推送到 Jitsi 房间
    var xmpp = new XMPPVideoRoom("meet.jit.si", null);
    xmpp.join(
      "testroom",
      "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov",
      "Bunny"
    );
  </script>
</head>
</html>

这样可以把摄像头/RTSP 流转换为 WebRTC 流并加入到 Jitsi 房间,作为一个虚拟参会者。


7. 依赖与源码编译

如果你希望从源码构建 WebRTC-Streamer(例如自定义某些编译选项或集成特定版本的 WebRTC),可以参考官方提供的编译步骤。

7.1 主要依赖

  • WebRTC Native Code Package(来自 chromium 项目);
  • civetweb:作为 HTTP 服务器;
  • live555:RTSP/MKV 源处理;
  • 以及 CMake、编译工具链等。

7.2 编译步骤概览

  1. 安装 Chromium depot tools

    pushd ..
    git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
    export PATH=$PATH:`realpath depot_tools`
    popd
    
  2. 下载 WebRTC 源码:

    mkdir ../webrtc
    pushd ../webrtc
    fetch webrtc
    popd
    
  3. 构建 WebRTC-Streamer:

    cmake . && make
    

构建时可以通过 CMake 变量控制 WebRTC 源码路径/桌面捕获支持等:

  • WEBRTCROOT:指向 WebRTC 源码目录(一般是 ../webrtc);
  • WEBRTCDESKTOPCAPTURE:是否启用桌面捕获(默认 ON)。

提示:由于 WebRTC 源码体积与依赖较大,建议优先考虑官方 Releases 或 Docker 镜像,只有在有定制需求时再自行编译。

7.3 CI 流水线与多平台构建

官方仓库已经配置了多家 CI:

  • CircleCI;
  • CirrusCI;
  • GitHub Actions;

自动构建的目标包括:

  • Ubuntu x86_64;
  • 多种 ARM 交叉编译(Raspberry Pi/NanoPi 等);
  • Windows x64(clang);
  • macOS。

这意味着你可以直接从 Releases 中获得相对完整的多平台二进制包,无需自己维护复杂的交叉编译环境。


8. 实战建议与常见场景

8.1 用浏览器播放 RTSP 摄像头(单机调试)

  • 适用人群:需要快速验证摄像头画面在浏览器中能否正常播放的开发者;
  • 步骤:
    1. 启动 WebRTC-Streamer(本机或局域网一台机器);
    2. 通过 -n/-u 注册一个 RTSP 流,或直接传入 rtsp:// URL;
    3. 打开官方 HTML 示例或自建页面,连接到该流;
    4. 如遇到无法播放,优先检查:
      • HTTP 是否可访问;
      • 浏览器 Console 与 Network 是否报错;
      • 摄像头 RTSP URL 是否可在 VLC 等工具中拉流成功。

8.2 通过 Docker 部署多路 RTSP → WebRTC 网关

  • 适用人群:需要在服务器上集中管理多路摄像头,将其统一转成 WebRTC 给前端使用;
  • 建议:
    • 用 Docker + config.json 管理多路流;
    • 使用 --net host 或明确映射所需端口;
    • 使用反向代理(Nginx/Caddy 等)统一处理 HTTPS 与域名;
    • 配置外部 STUN/TURN 服务器,提升复杂网络下的连通率。

8.3 与 Janus/Jitsi 集成做多方会议/大屏展示

  • WebRTC-Streamer 专注于“拉各种源 → 转成 WebRTC”;
  • Janus/Jitsi 等平台则提供房间管理、多方会话、录制等能力;
  • 通过官方 JS 工具(JanusVideoRoom/XMPPVideoRoom)可以让摄像头/RTSP 流以“虚拟用户”的形式加入会议房间,实现更复杂的展示与互动场景。

9. 小结

WebRTC-Streamer 虽然项目本身不算庞大,但解决的是一个很实在的需求:

  • 把 RTSP/RTMP/本地采集/屏幕捕获等“传统流媒体输入”,转成浏览器可直接播放的 WebRTC 实时流
  • 支持内嵌 STUN/TURN,降低 NAT 场景的部署门槛;
  • 提供 HTML 示例、WebComponents、WHEP 等多种接入方式,方便放入你自己的前端项目;
  • 还能与 Janus/Jitsi 等 WebRTC 平台协同工作,形成更完整的实时音视频解决方案。

如果你正好有“把 RTSP 摄像头画面搬到浏览器里”、“把本地采集/屏幕捕获当作 WebRTC 流推到前端”之类的需求,可以先用 Docker 或预编译包跑起 WebRTC-Streamer 的 Demo,再结合本文的参数说明和嵌入示例,逐步接入到自己的系统中。

标签

#WebRTC-Streamer #WebRTC #RTSP #RTMP #Docker #STUN #TURN #WHEP #Janus #Jitsi

版权声明

本文由 WebRTC.link 创作,采用 CC BY-NC-SA 4.0 许可协议。本站转载文章会注明来源以及作者。如果您需要转载,请注明出处以及作者。

评论区

Giscus

评论由 Giscus 驱动,基于 GitHub Discussions

相关文章

探索更多相关内容,深入了解 WebRTC 技术的各个方面

演示 Demo

LIVE

基础摄像头访问

展示如何使用 getUserMedia API 获取摄像头和麦克风

媒体获取 体验

PTZ 摄像头控制

控制支持 PTZ 功能的摄像头进行平移、倾斜和缩放

媒体获取 体验

屏幕共享

使用 getDisplayMedia API 进行屏幕共享

媒体获取 体验