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 进行屏幕共享

媒体获取 体验