在上面的文章里,我们知道视频和媒体如何使用,但是在实际的研发过程中,我们还会针对多个轨道的情况。
主要过程
- 创建createOffer
A为呼叫方,在此阶段,将音视频流加入RTCPeerConnection对象中传输给另一端,
目前推荐使用addTrack或者addTransceiver来添加流。如果要多个track必须添加多个。
RTCRtpTransceiver可以理解为一个转发器,有audio和video两种类型,每个transceiver都有相应的sender和receiver,也就是说在协商完成前,我们就可以持有remote track的引用了,对于track的操作更加方便
- 应答createAnswer
从信令服务器收到A发过来的会话信息,调用setRemoteDescription方法将提案传递到ICE层,调用将音视频流加入加入RTCPeerConnction
- 接收远程对等方发送的媒体流。当接收到远程流时,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。每个收发器都代表一个双向流,并带有RTCRtpSender和RTCRtpReceiver。
如果只想建立音视频轨道,并不需要使用摄像头、麦克风,使用addTransceiver就可以了
语法
let rtcTransceiver = RTCPeerConnection .addTransceiver(trackOrKind,init);
- trackOrKind:MediaStreamTrack以与所述收发器相关联,或者一个DOMString被用作kind接收器的的track
这里视频轨道就传”video“,音频轨道就传”audio“
- init: 可选参数。如下:
streams:MediaStream要添加到收发器的对象列表RTCRtpReceiver;当远程对等方RTCPeerConnection的track事件发生时,这些是将由该事件指定的流。
例如 添加一个单向的音视频流收发器
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;};
RA/SD 衍生者AI训练营。发布者:chris,转载请注明出处:https://www.shxcj.com/archives/6546