#gstreamer #signaling-server #web-rtc #video-stream #element #signaller #webrtcsink

gst-plugin-webrtc

用于高级 WebRTC 元素和简单信令服务器的 GStreamer 插件

30 个版本

0.13.0 2024 年 7 月 16 日
0.12.7 2024 年 6 月 19 日
0.12.3 2024 年 3 月 21 日
0.11.3 2023 年 12 月 18 日
0.9.1 2022 年 11 月 13 日

#12视频

Download history 35/week @ 2024-05-04 32/week @ 2024-05-11 280/week @ 2024-05-18 81/week @ 2024-05-25 67/week @ 2024-06-01 46/week @ 2024-06-08 305/week @ 2024-06-15 111/week @ 2024-06-22 208/week @ 2024-06-29 207/week @ 2024-07-06 231/week @ 2024-07-13 279/week @ 2024-07-20 274/week @ 2024-07-27 371/week @ 2024-08-03 272/week @ 2024-08-10 106/week @ 2024-08-17

1,072 每月下载量
用于 srt_whep

MPL-2.0 许可证

650KB
14K SLoC

Rust 12K SLoC // 0.1% comments JavaScript 2.5K SLoC // 0.2% comments

包含(JAR 文件,60KB) gradle-wrapper.jar

webrtcsink 和 webrtcsrc

包含所有电池的 GStreamer WebRTC 生产者和消费者,尽力做到最好。

它还提供了一个灵活的多用途 WebRTC 信令服务器(gst-webrtc-signalling-server)和 JavaScript API(gstwebrtc-api),以从网页浏览器产生和消费兼容的 WebRTC 流。

用例

GStreamer 中的 webrtcbin 元素非常灵活和强大,但使用它可能是一个困难的练习。当您只想向任意数量的消费者提供一组固定的流时,内部包装 webrtcbinwebrtcsink(可作为一个有用的替代方案)。

特性

webrtcsink 实现以下特性

  • 内置信令器:当使用默认信令服务器时,此元素将执行信令而无需应用程序交互。这使得它可以直接从 gst-launch 使用。

  • 应用程序提供的信令:webrtcsink 可以由应用程序使用自定义信令器实例化。该信令器必须是 GObject,并且必须实现 Signallable 接口,如此处 定义。默认信令器可以作为示例使用。

    还提供了一个示例,可以作为实现和使用自定义信令器的模板。

  • 沙盒消费者:当添加消费者时,其编码器/打包器/webrtcbin 元素在单独管理的管道中运行。这提供了一定程度的沙盒,而不是让这些元素在元素内部运行。

    请注意,目前编码在消费者之间没有共享。虽然目前不在路线图上,但设计中没有阻止实施这种优化。

  • 拥塞控制:该元素利用传输范围内的拥塞控制反馈消息,以调整个别消费者视频编码器的比特率以适应可用带宽。

  • 配置:用户对元素的控制在慢慢扩展,有关可用属性和信号的更多信息,请参考 gst-inspect-1.0

  • 数据包丢失缓解:webrtcsink 现在支持发送用于前向纠错的保护数据包,将数量作为可用带宽的函数进行调制,并可以满足重传请求。这两个功能都可以通过属性禁用。

请注意,对 webrtcsink 使用的个别元素的完全控制目前不在路线图上,因为它在这方面将作为一个黑盒,例如 webrtcsink 想要保留对比特率的控制权以进行拥塞控制。

不过,现在有一个信号可供应用程序提供为 webrtcsink 实例化的编码器初始配置。

如果需要更细粒度的控制,应用程序应直接使用 webrtcbinwebrtcsink 将专注于尝试做正确的事,尽管它可能暴露更多接口以指导和调整它使用的启发式算法。

构建

在安装之前,请确保安装一些编解码器库的开发包,例如 libx264、libvpx 和 libopusenc,具体名称取决于您的发行版。

cargo build

使用方法

打开三个终端。在第一个终端中,运行信令服务器

cd signalling
WEBRTCSINK_SIGNALLING_SERVER_LOG=debug cargo run --bin gst-webrtc-signalling-server

在第二个终端中,运行一个网页浏览器客户端(可以产生和消费流)

cd gstwebrtc-api
npm install
npm start

在第三个终端中,从 GStreamer 管道运行 webrtcsink 生产者

export GST_PLUGIN_PATH=<path-to-gst-plugins-rs>/target/debug:$GST_PLUGIN_PATH
gst-launch-1.0 webrtcsink name=ws meta="meta,name=gst-stream" videotestsrc ! ws. audiotestsrc ! ws.

产生的 webrtcsink 流将出现在前面的网页中(在 https://127.0.0.1:9090 自动打开)下名为 "gst-stream",如果您点击它,应该会看到一个测试视频流并听到测试音。

您还可以从网页浏览器产生 WebRTC 流并用 GStreamer 管道消费它们。点击“开始捕获”按钮并复制“客户端 ID”值。

然后打开一个新的终端并运行

export GST_PLUGIN_PATH=<path-to-gst-plugins-rs>/target/debug:$GST_PLUGIN_PATH
gst-launch-1.0 playbin uri=gstwebrtc://127.0.0.1:8443?peer-id=[Client ID]

将“peer-id”值替换为之前复制的“客户端 ID”值。您应该看到 playbin 元素打开一个窗口并显示网页产生的内容。

配置

可以通过其属性配置 webrtcsink 元素本身,有关更多信息,请参阅 gst-inspect-1.0 webrtcsink。此外,默认信令器还公开了用于配置它的属性,特别是设置信令服务器地址,可以通过 gst::ChildProxy 接口访问这些属性,例如使用 gst-launch。

gst-launch-1.0 webrtcsink signaller::uri="ws://127.0.0.1:8443" ..

启用“导航”,即用户与内容的交互

webrtcsink 实现了 GstNavigation 接口,允许与内容进行交互,例如使用鼠标移动、通过键盘输入按键等。在此基础上,还实现了一个基于 WebRTCDataChannel 的协议,可以通过设置 enable-data-channel-navigation=true 属性来激活,允许客户端通过 WebRTC 数据通道发送 GstNavigation 事件。

gstwebrtc-apiwebrtcsrc 也实现了该协议,可以作为客户端来控制远程服务器。

您可以使用以下管道和 wpesrc 元素轻松测试此功能,该管道将启动一个服务器,允许您浏览 GStreamer 文档

gst-launch-1.0 wpesrc location=https://gstreamer.freedesktop.org/documentation/ ! queue ! webrtcsink enable-data-channel-navigation=true meta="meta,name=web-stream"

您可以在 Web 浏览器内的视频中控制它(如果已遵循该说明中的先前步骤,则在 https://127.0.0.1:9090)或使用以下 GSteamer 管道作为客户端

gst-launch-1.0 webrtcsrc signaller::producer-peer-id=<webrtcsink-peer-id> enable-data-channel-navigation=true ! videoconvert ! autovideosink

发送 HTTP 头部信息

在初始信令服务器握手期间,您可以选择传输 HTTP 头部信息,这可以用于认证目的或粘性会话等。

gst-launch-1.0 webrtcsink signaller::uri="ws://127.0.0.1:8443" signaller::headers="headers,foo=bar,cookie=\"session=1234567890; foo=bar\""

测试拥塞控制

为了以可重复的方式测试拥塞,使用了 简单工具,它仅在 Linux 上使用,但也被记录为可在 MacOS 上使用。客户端 Web 浏览器需要在局域网上的另一台机器上启动以测试拥塞,尽管特定的配置可能允许在同一台机器上运行。

测试步骤如下

  • 识别服务器机器的网络接口(例如,在 Linux 上使用 ifconfig

  • 识别客户端机器的 IP 地址(例如,在 Linux 上使用 ifconfig

  • 按照用法部分中所述启动各种服务(使用 GST_DEBUG=webrtcsink:7 获取有关拥塞控制的详细日志)

  • 在客户端浏览器中开始播放

  • 在服务器机器上运行 comcast 命令,例如

    $HOME/go/bin/comcast --device=$SERVER_INTERFACE --target-bw 3000 --target-addr=$CLIENT_IP --target-port=1:65535 --target-proto=udp
    
  • 观察比特率急剧下降,播放应暂时减慢然后恢复

  • 移除带宽限制,并观察比特率最终增加到最大值

    $HOME/go/bin/comcast --device=$SERVER_INTERFACE --stop
    

为了比较,可以将 webrtcsink 上的拥塞控制属性设置为 "disabled",然后再次应用上述程序,预期结果是播放简单地慢下来直到带宽限制解除

gst-launch-1.0 webrtcsink congestion-control=disabled

监控工具

有关监控每个消费者统计信息的客户端/服务器应用程序示例,请参阅 此处

许可证

此存储库中所有 Rust 代码均根据 Mozilla 公共许可证版本 2.0 许可。

gstwebrtc-api 中的代码也根据 Mozilla 公共许可证版本 2.0 许可。

使用 AWS KVS 信令器

AWS_ACCESS_KEY_ID="XXX" AWS_SECRET_ACCESS_KEY="XXX" gst-launch-1.0 videotestsrc pattern=ball ! video/x-raw, width=1280, height=720 ! videoconvert ! textoverlay text="Hello from GStreamer!" ! videoconvert ! awskvswebrtcsink name=ws signaller::channel-name="XXX"

使用WHIP信令器

WHIP客户端

WHIP客户端信令器使用BaseWebRTCSink

通过设置janus和https://github.com/meetecho/simple-whip-server/来测试WHIP客户端作为信令器的功能。

  • 设置一个janus实例,并配置videoroom插件以公开ID为1234的房间(配置在janus.plugin.videoroom.jcfg

  • 打开网页 <janus/share/janus/demos/videoroomtest.html>,点击开始并加入房间

  • 按照其README中的说明设置simple whip server

  • 导航到https://127.0.0.1:7080/,创建一个名为room1234的端点,指向ID为1234的Janus房间

  • 最后,通过以下命令向端点发送流

gst-launch-1.0 -e uridecodebin uri=file:///home/meh/path/to/video/file ! \
  videoconvert ! video/x-raw ! queue ! \
  whipwebrtcsink name=ws signaller::whip-endpoint="http://127.0.0.1:7080/whip/endpoint/room1234"

你应该会在videoroomtest网页中看到第二个视频显示。

WHIP服务器

WHIP服务器信令器使用BaseWebRTCSrc

作为信令器的WHIP服务器可以通过两种方式测试。

注意:whipserversrc的初始版本不检查任何认证或加密。在HTTP(s)代理后面使用whipserversrc的宿主应用程序可以强制执行WHIP客户端和服务器之间的认证和加密

1. 使用Gstreamer元素whipwebrtcsink

a. 在终端的一个标签页中,使用以下命令启动WHIP服务器

RUST_BACKTRACE=full GST_DEBUG=webrtc*:6 GST_PLUGIN_PATH=target/x86_64-unknown-linux-gnu/debug:$GST_PLUGIN_PATH gst-launch-1.0 whipserversrc signaller::host-addr=http://127.0.0.1:8190 stun-server="stun://stun.l.google.com:19302" turn-servers="\<\"turns://user1:[email protected]:7806\", \"turn://user2:[email protected]:7809\"\>" ! videoconvert ! autovideosink

b. 在第二个标签页中,通过以下命令启动WHIP客户端,发送测试视频

RUST_BACKTRACE=full GST_DEBUG=webrtc*:6 GST_PLUGIN_PATH=target/x86_64-unknown-linux-gnu/debug:$GST_PLUGIN_PATH gst-launch-1.0 videotestsrc ! videoconvert ! video/x-raw ! queue ! \
  whipwebrtcsink name=ws signaller::whip-endpoint="http://127.0.0.1:8190/whip/endpoint"

2. 使用Meetecho的simple-whip-client

按照https://github.com/meetecho/simple-whip-client#readme中的说明设置simple whip客户端

a. 在终端的一个标签页中,使用以下命令启动WHIP服务器

RUST_BACKTRACE=full GST_DEBUG=webrtc*:6 GST_PLUGIN_PATH=target/x86_64-unknown-linux-gnu/debug:$GST_PLUGIN_PATH gst-launch-1.0 whipserversrc signaller::host-addr=http://127.0.0.1:8190 stun-server="stun://stun.l.google.com:19302" turn-servers="\<\"turns://user1:[email protected]:7806\", \"turn://user2:[email protected]:7809\"\>" name=ws ! videoconvert ! autovideosink ws. ! audioconvert ! autoaudiosink

b. 在第二个标签页中,按照以下命令启动simple-whip-client

./whip-client --url http://127.0.0.1:8190/whip/endpoint \
        -A "audiotestsrc is-live=true wave=red-noise ! audioconvert ! audioresample ! queue ! opusenc perfect-timestamp=true ! rtpopuspay pt=100 ssrc=1 ! queue ! application/x-rtp,media=audio,encoding-name=OPUS,payload=100" \
        -V "videotestsrc is-live=true pattern=ball ! videoconvert ! queue ! vp8enc deadline=1 ! rtpvp8pay pt=96 ssrc=2 ! queue ! application/x-rtp,media=video,encoding-name=VP8,payload=96" \
        -S stun://stun.l.google.com:19302 \
        -l 7 \
        -n true

终止客户端将关闭会话,客户端应收到DELETE请求的200(OK)响应

使用LiveKit信令器

通过设置LiveKit并创建一个房间来测试LiveKit信令器。

您可以通过提供API密钥和秘密来连接

gst-launch-1.0 -e uridecodebin uri=file:///home/meh/path/to/video/file ! \
  videoconvert ! video/x-raw ! queue ! \
  livekitwebrtcsink signaller::ws-url=ws://127.0.0.1:7880 signaller::api-key=devkey signaller::secret-key=secret signaller::room-name=testroom

或者通过使用单独创建的认证令牌

gst-launch-1.0 -e uridecodebin uri=file:///home/meh/path/to/video/file ! \
  videoconvert ! video/x-raw ! queue ! \
  livekitwebrtcsink signaller::ws-url=ws://127.0.0.1:7880 signaller::auth-token=mygeneratedtoken signaller::room-name=testroom

你应该会在videoroomtest网页中看到第二个视频显示。

使用livekitwebrtcsrc元素从LiveKit进行流式传输

首先,使用以下命令将流发布到房间

gst-launch-1.0 livekitwebrtcsink name=sink \
    signaller::ws-url=ws://127.0.0.1:7880 \
    signaller::api-key=devkey \
    signaller::secret-key=secret \
    signaller::room-name=testroom \
    signaller::identity=gst-producer \
    signaller::participant-name=gst-producer \
    video-caps='video/x-h264' \
  videotestsrc is-live=1 \
  ! video/x-raw,width=640,height=360,framerate=15/1 \
  ! timeoverlay ! videoconvert ! queue ! sink.

然后回放发布的流

gst-launch-1.0 livekitwebrtcsrc \
    name=src \
    signaller::ws-url=ws://127.0.0.1:7880 \
    signaller::api-key=devkey \
    signaller::secret-key=secret \
    signaller::room-name=testroom \
    signaller::identity=gst-consumer \
    signaller::participant-name=gst-consumer \
    signaller::producer-peer-id=gst-producer \
    video-codecs='<H264>' \
  src. ! queue ! videoconvert ! autovideosink

使用livekitwebrtcsrc元素自动订阅

使用LiveKit源元素,您也可以通过不指定任何值来订阅您房间中的所有对等方,即不指定signaller::producer-peer-id。也可以通过向signaller::excluded-producer-peer-ids提供对等方ID数组来忽略不需要的对等方。重要的是,还需要添加源元素已订阅的房间中所有流的接收器。

首先,使用不同的连接发布几个流

gst-launch-1.0 \
  livekitwebrtcsink name=sinka \
    signaller::ws-url=ws://127.0.0.1:7880 \
    signaller::api-key=devkey \
    signaller::secret-key=secret \
    signaller::room-name=testroom \
    signaller::identity=gst-producer-a \
    signaller::participant-name=gst-producer-a \
    video-caps='video/x-vp8' \
  livekitwebrtcsink name=sinkb \
    signaller::ws-url=ws://127.0.0.1:7880 \
    signaller::api-key=devkey \
    signaller::secret-key=secret \
    signaller::room-name=testroom \
    signaller::identity=gst-producer-b \
    signaller::participant-name=gst-producer-b \
    video-caps='video/x-vp8' \
  livekitwebrtcsink name=sinkc \
    signaller::ws-url=ws://127.0.0.1:7880 \
    signaller::api-key=devkey \
    signaller::secret-key=secret \
    signaller::room-name=testroom \
    signaller::identity=gst-producer-c \
    signaller::participant-name=gst-producer-c \
    video-caps='video/x-vp8' \
  videotestsrc is-live=1 \
  ! video/x-raw,width=640,height=360,framerate=15/1 \
  ! timeoverlay ! videoconvert ! queue ! sinka. \
  videotestsrc pattern=ball is-live=1 \
  ! video/x-raw,width=320,height=180,framerate=15/1 \
  ! timeoverlay ! videoconvert ! queue ! sinkb.
  videotestsrc is-live=1 \
  ! video/x-raw,width=320,height=180,framerate=15/1 \
  ! timeoverlay ! videoconvert ! queue ! sinkc.

然后通过排除对等方C只观看A和B的流

gst-launch-1.0 livekitwebrtcsrc \
  name=src \
  signaller::ws-url=ws://127.0.0.1:7880 \
  signaller::api-key=devkey \
  signaller::secret-key=secret \
  signaller::room-name=testroom \
  signaller::identity=gst-consumer \
  signaller::participant-name=gst-consumer \
  signaller::excluded-producer-peer-ids='<gst-producer-c>' \
  src. ! queue ! videoconvert ! autovideosink
  src. ! queue ! videoconvert ! autovideosink

依赖项

~22–42MB
~794K SLoC