虽然 WebRTC 最初的重点是视频会议,但它也可以用于实时广播或具有超低延迟的流媒体(DASH-IF WebRTC 报告)。然而,在这种情况下使用 WebRTC 的采用率一直很慢,原因之一是缺乏用于摄取(生产者)和播放(查看者)的标准协议。

IETF 标准草案WHIP正在解决摄取方面的问题,该标准允许您将媒体从符合 WHIP 的发送软件发送到符合 WHIP 的媒体服务器。 WHIP 提出了一个简单的基于 HTTP 的协议,该协议将允许基于 WebRTC 将内容摄取到流服务和/或 CDN 中。

在播放方面,有一些标准化计划正在讨论中,但进展不如在摄取方面与 WHIP 的进展。 WebRTC 媒体服务器提供 WebRTC 播放器,但它们通常与特定的 WebRTC 媒体服务器绑定。

由于我们还没有达到媒体服务器(广播公司)和播放器之间的 SDP 交换的通用标准(传输方法),因此我们已经启动了一个开源项目,用于媒体服务器独立 WebRTC 播放器。

[WebRTC播放器示例](https://res.cloudinary.com/practicaldev/image/fetch/s--ox0UkeIT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/6lfidqn7cfks9kqc8kod.png)

具有媒体服务器适配器的播放器,您可以在其中使用其中一个包含的适配器,也可以构建您自己使用的自定义适配器。我们欢迎以媒体服务器适配器的形式为这个项目做出贡献,这篇博文将引导您了解如何使用和添加适配器

使用方法

如果您只想将 WebRTC 播放器与任何包含的适配器一起使用,下面的 HTML 和 Javascript 将为您提供示例。

<html>
  <head><script type="module" src="index.ts"></script></head>
  <body>
    <video autoplay muted controls>
    <button id="play">Play</button>
  </body>
</html>

进入全屏模式 退出全屏模式

以及 Javascript(打字稿)代码。

import { WebRTCPlayer, ListAvailableAdapters } from "@eyevinn/webrtc-player";

const video = document.querySelector("video");
const iceServers = [{ urls: "stun:stun.l.google.com:19302" }];
document.querySelector<HTMLButtonElement>("#play").addEventListener("click", async () => {
  const channelUrl = "<media-server-url-to-channel>";
  const player = new WebRTCPlayer({ 
    video: video,
    type: "se.eyevinn.webrtc",
    iceServers: iceServers 
  });
  await player.load(new URL(channelUrl));
});

进入全屏模式 退出全屏模式

字符串se.eyevinn.webrtc指定将包含的适配器用于Eyevinn WebRTC WHIP-broadcaster。要获取可用适配器的列表,您可以执行以下操作。

ListAvailableAdapters().forEach(adapterType => {
  console.log(adapterType);
}

进入全屏模式 退出全屏模式

开发自定义适配器

如果您想使用此 WebRTC 播放器,但使用您自己的媒体服务器,您可以开发自定义适配器并使用该适配器。当您创建播放器的实例时,您提供了一个AdapterFactoryFunction,它将返回一个扩展基类BaseAdapter的适配器的新实例。

const player = new WebRTCPlayer({
  video: video, 
  type: "custom", 
  adapterFactory: (peer: RTCPeerConnection, channelUrl: URL) => {
    return new CustomAdapter(peer, channelUrl);
  }
});

进入全屏模式 退出全屏模式

在构造函数中设置type === "custom"和工厂函数。下面是自定义适配器的模板。

import { BaseAdapter } from "@eyevinn/webrtc-player";

class CustomAdapter extends BaseAdapter {
  constructor(peer: RTCPeerConnection, channelUrl: URL) {
    super(peer, channelUrl);
  }

  // Overload SDP exchange method
  async exchangeSdp() {
    // do stuff here
  }
}

进入全屏模式 退出全屏模式

exchangeSdp()函数用于实现媒体服务器特定的交换 SDP 的方式。例如:

async exchangeSdp() {
  const response = await fetch(this.channelUrl.href, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ sdp: this.localPeer.localDescription.sdp })
  });
  if (response.ok) {
    const { sdp } = await response.json();
    this.localPeer.setRemoteDescription({ type: "answer", sdp: sdp });
  }
}

进入全屏模式 退出全屏模式

在上面的示例中,本地 SDP 与 HTTP POST 一起发送到媒体服务器,媒体服务器返回远程 SDP。

贡献

如果您想包括对您的媒体服务器的支持或一般性的贡献,我们很高兴向这个项目提出拉取请求。要将适配器添加到项目中,您首先以与上述相同的方式创建适配器,但还要将其包含在adapters文件夹中的存储库中。然后将您的唯一字符串与工厂函数一起添加到adapters/factory.ts中的适配器列表中。

相关开源项目

  • WebRTC HTTP 摄取协议的客户端和服务器模块

  • 基于WHIP的超简单网络直播应用

关于Eyevinn Technology

Eyevinn Technology 是一家专注于视频和流媒体的独立顾问公司。以我们不与任何平台或技术供应商在商业上挂钩的方式独立。

在 Eyevinn,每位软件开发顾问都有专门的预算用于开源开发和对开源社区的贡献。这为我们提供了创新、团队建设和个人能力发展的空间。并且还为我们作为一家公司提供了一种回馈开源社区的方式。

想了解更多关于 Eyevinn 以及它是如何在这里工作的信息。通过work@eyevinn.se联系我们!

Logo

ModelScope旨在打造下一代开源的模型即服务共享平台,为泛AI开发者提供灵活、易用、低成本的一站式模型服务产品,让模型应用更简单!

更多推荐