WebRTC进阶七 / 如何控制音视频开关

1,523 阅读3分钟

这个场景是在实时音视频中非常常见的需求,但是你有想过,这个控制音视频的开关应该怎么实现吗,如何关闭我的音视频或者关闭别人的音视频。 那么针对这个场景,我们一个一个来进行解析

开关远端声音

方法一:

将video标签添加一个muted属性,如果你的音频是通过audio标签处理的,你也可以添加一个muted属性到audio中

<video src='xxx' autoplay playsinline muted></video>

当然你可能有切换muted状态的需求,还可以使用setAttribute()和removeAttribute()方法来添加和移除属性,如下所示:

//添加`muted`属性:
document.getElementById('yourVideo').setAttribute('muted', '');
//移除`muted`属性:
document.getElementById('yourVideo').removeAttribute('muted');

方法二:

你可以通过获取远端流的音轨,然后将其禁用或开启.

// 创建RTCPeerConnection对象
let pc = new RTCPeerConnection();
let remoteStream
// 设置ontrack回调函数
pc.ontrack = function(stream) {
  // 获取远程流对象
   if (stream.track.kind === 'audio') {
       remoteStream = stream.streams[0];
   }
};
// remoteStream为获取到的远程流对象
remoteStream.getAudioTracks().forEach(function(track) {
  // 对每个音频轨道设置enabled属性为false,即关闭声音,true为开启声音
  track.enabled = false;
});

方法三:

你可以通过远端流的RTCPeerConnection获取receivers,然后再寻找到对应的音频轨道,并将enable关闭

// pc为获取到的远端流的RTCPeerConnection
const getReceivers = pc.getReceivers();
let audio = getReceivers.find((receiver) => receiver.track.kind === 'audio');
//给音轨关闭声音,true为开启
audio.track.enabled = false;

开关远端流的视频

要关闭远端的视频流,是和上面的关闭远端的音频流是一样的,只需要将audio替换成video即可。这里就不演示了。

开关本地的视频

在这里是要区分情况的,一种是使用stop函数进行停止,这个的好处是可以将设备的占用终止,也就是在pc和手机上看到的摄像头灯会熄灭。第二种是通过enabled关闭,这个就不会终止设备占用。但是还有一个要注意的是,如果你已经通过 RTCPeerConnection 的 addTrack() 方法将本地媒体流添加到对等连接中,如果要关闭上行带宽连接,最好需要通过 RTCPeerConnection 的 removeTrack()来移除对应的视频流。下面是代码示例。

方法一:通过enable关闭

// 获取本地视频轨道
const localVideoTrack = localStream.getVideoTracks()[0];

// 关闭本地视频流
localVideoTrack.enabled = false;

// 查找与本地视频轨道关联的 RTCRtpSender 对象,peerConnection为本地的peer对象
const sender = peerConnection.getSenders()
  .find(sender => sender.track === localVideoTrack);

// 将 RTCRtpSender 对象从对等连接中移除
peerConnection.removeTrack(sender);

//要重新打开本地视频流,请使用 addTrack() 方法将本地视频轨道添加回对等连接中,同时需要将 `enabled` 属性设置为 true
// 将本地视频轨道添加回对等连接中
peerConnection.addTrack(localVideoTrack, localStream);

// 打开本地视频流
localVideoTrack.enabled = true;

方法二:通过stop关闭

stop方法的效果是立即停止摄像头采集,这会将导致对等连接中的远端停止接收本地视频流。如果需要重新启动本地视频流,需要重新调用 getUserMedia() 方法并将返回的媒体流添加到对等连接中。

// 获取本地视频轨道
const localVideoTrack = localStream.getVideoTracks()[0];

// 停止本地视频流
localVideoTrack.stop();

开关本地音频

要关闭本地音频流,是和上面关闭视频流的方法是一样的,只是将video替换从audio,这里就不再赘述了。

总结

通过上面的介绍,你应该知道如何进行开关本地和远端的音视频了,具体你要怎么实现,你可以按需来处理。

其实如果你是SFU的架构,对于关闭本地或远端摄像头你还可以停止转发对应用户的流,只不过这里需要服务端来实现了。