这个场景是在实时音视频中非常常见的需求,但是你有想过,这个控制音视频的开关应该怎么实现吗,如何关闭我的音视频或者关闭别人的音视频。 那么针对这个场景,我们一个一个来进行解析
开关远端声音
方法一:
将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的架构,对于关闭本地或远端摄像头你还可以停止转发对应用户的流,只不过这里需要服务端来实现了。