You need to enable JavaScript to run this app.
导航

构建基础应用

最近更新时间2023.02.06 11:18:14

首次发布时间2022.08.30 14:30:08

本文以 Web 平台为例,介绍如何在项目中,实现音视频发布流和订阅流功能。

参考示例项目

参考示例项目

前提条件

  • 控制台创建 WTN 应用,在快速体验页面获取发布和订阅流的地址。
  • 满足以下条件的计算机:
    • 搭载 Intel 第二代酷睿处理器或更佳性能的处理器;
    • 有可用的物理音视频采集设备,如内置摄像头和麦克风;
    • 安装最新版本的 Chrome 浏览器,并设置为默认浏览器;
    • 具备互联网连接。

实现功能

一次简单的音视频通话的流程图如下:

alt

实现一次简单的音视频通话主要包含以下步骤:

1. 发布端: 创建和初始化客户端对象

调用浏览器原生 getUserMedia 创建一个本地音视频流,并保存音视频轨道。

// See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints.
const stream:MediaStream=  await navigator.mediaDevices.getUserMedia(options as MediaStreamConstraints)
const videoTrack = mediaStream.getVideoTracks()[0];
const audioTrack = mediaStream.getAudioTracks()[0];

2. 发布端创建 PeerConnection,添加 transceiver,设置 offer

const peer = new RTCPeerConnection({})

const ms = new MediaStream()
// 添加音视频轨道
if (audioTrack) ms.addTrack(audioTrack);
if (videoTrack) ms.addTrack(videoTrack);

peer.addTransceiver(audioTrack || "audio",{
    streams:[ms],
    direction:"sendonly"
})

peer.addTransceiver(videoTrack || "video",{
    streams:[ms],
    direction:"sendonly"
})

// 创建 P2P offer
const offer = await peer.createOffer();

// 设置本地 offer
// 参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription
peer.setLocalDescription(offer);
  1. 订阅端创建 PeerConnection,添加 transceiver,设置 offer

const peer = new RTCPeerConnection({})

peer.addTransceiver("audio",{
    direction:"recvonly"
})

peer.addTransceiver("video",{
    direction:"recvonly"
})

// 创建 P2P offer
const offer = await peer.createOffer();

// 设置本地 offer
// 参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription
peer.setLocalDescription(offer);

4. 发布端和订阅端:与 veWTN 服务器通信,交换 offer

// 通过 veWTN 服务交换 offer
const res = await fetch(YOUR_PUSH_URL||YOUR_PULL_URL, { method: 'POST', body: offer.sdp, headers });

if (!res.ok) {
  return res;
}

// 可以在 headers 里获取到断开链接的请求地址
const resourceURL = new URL(res.headers.get('location') || '', url);

const sdp = await res.text();
const answer = new RTCSessionDescription({ type: 'answer', sdp });
await peerConn.setRemoteDescription(answer);

5. 订阅端:订阅和播放音视频流

发布订阅的双方交换 SDP 之后,peerConnection 就已经成功建联。此时订阅端 peerConnection 可在回调 ontrack 中接收到发布端的音视频流。

peer.ontrack = function (event) {
  if (event && event.streams) {
    if (event.track.kind === 'video') {
      const player =  document.querySelector("#video");
      player.onloadeddata = () =>{
        player.play();
      }
      // 设置播放器的 srcObject 属性为接收到的流
      player.current.srcObject = event.streams[0];
    }
  }
};

6. 发布端和订阅端:断开 PeerConnection

断开 PeerConnection 后,音视频流的发布和接收也将停止。

peer.close();
peer = undefined;

fetch(resourceURL.href, { method: 'DELETE' });

至此,我们实现了基础的音视频通话。