请先阅读原文,链接:从头到脚撸一个多人视频聊天 — 前端 WebRTC 实战(一),本文只涉及实践过程中的问题
先看chrome时,没看到该属性,查询MDN也显示没有这属性。但后测试Chrome ,Safari, ff ,又发现都有该属性
谷歌,ff 不需要,Safari需要!
除了文中提到的: getAudioTracks()、getVideoTracks() ,还有stream.getTracks() 可以获取它们。 通过音、视频的Track,可以监听它们的设备名字,静音或结束时的事件。 注意的是,<video>元素只有play,seek,end,volumechange 等事件,没有mute事件的。
但是在我测试中,无法监听到Track的onmute事件, 而且muted属性一直是false.
整个过程看得不是太懂,由于源码我安装npm不成功,所以把代码摘出来。看一下它的执行流程:
<div class="demo">
<div class="rtcBox">
<div>
<video src="" id="rtcA" controls autoplay></video>
<h5>A</h5>
</div>
<div>
<video src="" id="rtcB" controls autoplay></video>
<h5>B</h5>
<button id="call">call</button>
<button id="hangup">hangup</button>
</div>
</div>
</div>
let peerA,peerB;
async function init() {
//1、 保存本地流到全局
this.localstream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
let video = document.querySelector('#rtcA');
video.srcObject = this.localstream;
//2、 创建A,B输出端
let PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
peerA = new PeerConnection();
peerA.addStream(this.localstream); // 添加本地流
console.log("1、 打开A 视频流,并放入peerA")
// 监听 A 的ICE候选信息 如果收集到,就添加给 B
peerA.onicecandidate = (event) => {
console.log('9、 10、 A onicecandidate', event);
if (event.candidate) {
peerB.addIceCandidate(event.candidate);
}
};
peerB = new PeerConnection();
// 监听 B 的ICE候选信息 如果收集到,就添加给 A
peerB.onicecandidate = (event) => {
console.log('4、5、12、 B onicecandidate', event);
if (event.candidate) {
peerA.addIceCandidate(event.candidate);
}
};
//3、 监听是否有媒体流接入,如果有就赋值给 rtcB 的 src
peerB.onaddstream = (event) => {
console.log('11、 event-stream', event);
let video = document.querySelector('#rtcB');
video.srcObject = event.stream;
};
}
document.getElementById("call").addEventListener("click", async function () {
//4、B发起呼叫
let offer = await peerB.createOffer( {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1
}); // 创建 offer
console.log("2、 创建offer")
await peerB.setLocalDescription(offer); // 呼叫端设置本地 offer 描述
console.log("3、 B set offer后")
await peerA.setRemoteDescription(offer); // 接收端设置远程 offer 描述
console.log(" 6、 A set offer 后")
//A响应
let answer = await peerA.createAnswer(); // 接收端创建 answer
console.log("7、 创建answer")
await peerA.setLocalDescription(answer); // 接收端设置本地 answer 描述
console.log(" 8、 A set answer 后")
await peerB.setRemoteDescription(answer); // 呼叫端设置远程 answer 描述
console.log("13、 B set answer 后")
});
document.getElementById("hangup").addEventListener("click", function () {
//5、 断开
peerA.close();
peerB.close();
peerA = null;
peerB = null;
this.allowCall = false;
this.allowHangup = true
console.log("14、 断开")
})
init();
通过打印消息出现的顺序,可以看到执行过程: