第十七章 实现多通道音视频数据流支持

在上面的文章里,我们知道视频和媒体如何使用,但是在实际的研发过程中,我们还会针对多个轨道的情况。

主要过程

  1. 创建createOffer

A为呼叫方,在此阶段,将音视频流加入RTCPeerConnection对象中传输给另一端,

目前推荐使用addTrack或者addTransceiver来添加流。如果要多个track必须添加多个。

RTCRtpTransceiver可以理解为一个转发器,有audio和video两种类型,每个transceiver都有相应的sender和receiver,也就是说在协商完成前,我们就可以持有remote track的引用了,对于track的操作更加方便

  1. 应答createAnswer

从信令服务器收到A发过来的会话信息,调用setRemoteDescription方法将提案传递到ICE层,调用将音视频流加入加入RTCPeerConnction

  1. 接收远程对等方发送的媒体流。当接收到远程流时,RTC对等连接会触发轨道事件。我们可以在这个事件的处理函数中获取到远程流,并将其显示在页面上 RTCPeerConnection.onTrack

主要API

AddTrack方法

将一个MediaStream音频或视频的本地源,添加到WebRTC对等连接流对象中。官方推荐我们使用方法addTrack

RTCPeerConnection.addTrack()将新的媒体轨道添加到轨道集,该轨道将被传输到另一对等方

const mediaConstraints = {audio: true, // 我们需要一个音频轨道video: true, // 以及一个视频轨道};const desc = new RTCSessionDescription(sdp);

pc.setRemoteDescription(desc).then(() => navigator.mediaDevices.getUserMedia(mediaConstraints)).then((stream) => {
    previewElement.srcObject = stream;

    stream.getTracks().forEach((track) => pc.addTrack(track, stream));});

这段代码获取从远程对等端接收到的 SDP,并构造一个新的 RTCSessionDescription 实例并传递到 setRemoteDescription()。执行成功后,使用 MediaDevices.getUserMedia 来访问本地摄像头和麦克风。

如果(调用)成功,则将拿到的流作为变量 previewElement 所指向的 <video> 元素的源输入给它。

这是通过遍历 MediaStream.getTracks() 返回的列表中的每个轨道,并将它们与其所属的流一起传递给 addTrack() 方法来完成的。

在音视频聊天相关场景时,addTrack 能满足需求,这需要使用到用户的摄像头、麦克风(浏览器会询问用户是否授权)

AddTransceiver方法

addTransceiver创建一个新的RTCRtpTransceiver并将其添加到与关联的收发器集中RTCPeerConnection。每个收发器都代表一个双向流,并带有RTCRtpSenderRTCRtpReceiver

如果只想建立音视频轨道,并不需要使用摄像头、麦克风,使用addTransceiver就可以了

语法

let rtcTransceiver = RTCPeerConnection .addTransceiver(trackOrKind,init);

  • trackOrKind:MediaStreamTrack以与所述收发器相关联,或者一个DOMString被用作kind接收器的的track

这里视频轨道就传"video",音频轨道就传"audio"

  • init: 可选参数。如下:

streams:MediaStream要添加到收发器的对象列表RTCRtpReceiver;当远程对等方RTCPeerConnectiontrack事件发生时,这些是将由该事件指定的流。

例如 添加一个单向的音视频流收发器

this.rtcPeerConnection.addTransceiver("video", {                
    direction: "recvonly"            
});            
this.rtcPeerConnection.addTransceiver("audio", {                
    direction: "recvonly"            
});

上述代码只会接收对端发过来的音视频流,不会将自己的音视频流传输给对端。

direction:

RTCRtpSender 的行为RTCRtpReceiver 的行为
"sendrecv"可以发送 RTP 数据,如果另一个对等节点接受了连接,且至少有一个 sender 的处于编码状态,则发送数据。可以接收 RTP 数据,如果有其他的对等节点接受数据,则接收数据。
"sendonly"可以发送 RTP 数据,如果另一个对等节点接受了连接,且至少有一个 sender 的处于编码状态,则发送数据。不可以接收 RTP 数据,无论如何都不会接收数据。
"recvonly"不可以发送 RTP 数据,无论如何都不会发送数据。可以接收 RTP 数据,如果有其他的对等节点接受数据,则接收数据。
"inactive"不可以发送 RTP 数据,无论如何都不会发送数据。不可以接收 RTP 数据,无论如何都不会接收数据。

ontrack事件

RTCPeerConnection.ontrack 属性是一个事件处理器,此属性指定了在 RTCPeerConnection接口上触发 track 事件时调用的方法。该方法接收一个 RTCTrackEvent 类型的 event 对象,该 event 对象将在 MediaStreamTrack 被创建时或者是关联到已被添加到接收集合的 RTCRtpReceiver 对象中时被发送。

参数

将ontrack设置为你提供的一个输入RTCTrackEvent对象用于描述新的 track 将如何使用的方法。这一信息包含了代表新 track 的MediaStreamTrack对象、RTCRtpReceiver对象、RTCRtpTransceiver对象以及一个MediaStream对象列表,该对象列表表示该 track 是那个媒体流的一部分。

本示例,从这篇文章的代码和视频调用的代码中,将传入的轨迹连接到将用于显示传入元素

pc.ontrack = function (event) {
  document.getElementById("received_video").srcObject = event.streams[0];
  document.getElementById("hangup-button").disabled = false;};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉达曼迪斯II

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值