这是我参与「第五届青训营」伴学笔记创作活动的第 5 天
书接上文:WebRTC(一)MediaStream
在上文中,我们已经从MediaStream拿到了音频流和视频流,但自己自娱自乐看自己直播可没什么劲,我们要把画面声音推给其他人看
这里就需要我们跟其他人建立连接,这就需要今天的RTCPeerConnection
一般来说,为了保证不同浏览器的兼容问题,我们需要引入adapter来保证兼容性
CDN:
webrtc.github.io/adapter/ada… lf9-cdn-tos.bytecdntp.com/cdn/expire-…
先看示例代码吧:
这个页面上有三个按钮:开始 call 挂断
我们一个一个看
开始按钮和上文几乎一样,先拿到本地的媒体流
然后推送给video标签让他播放
核心代码:
function startAction() {
startButton.disabled = true;
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
}
call按钮的工作简单地说就是把流推给远端,具体的介绍看下面代码的注释吧
核心代码:
function callAction() {
callButton.disabled = true;
hangupButton.disabled = false;
console.log('Starting call.');
// 获取本地流的轨道,localStream就是前面获取到的媒体流
const videoTracks = localStream.getVideoTracks();
const audioTracks = localStream.getAudioTracks();
const servers = null;
// 创建本地peer连接对象
localPeerConnection = new RTCPeerConnection(servers);
console.log('Created local peer connection object localPeerConnection.');
//icecandidate事件的介绍:
//https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection/icecandidate_event
localPeerConnection.addEventListener('icecandidate', handleConnection);
localPeerConnection.addEventListener(
'iceconnectionstatechange', handleConnectionChange);
remotePeerConnection = new RTCPeerConnection(servers);
console.log('Created remote peer connection object remotePeerConnection.');
remotePeerConnection.addEventListener('icecandidate', handleConnection);
remotePeerConnection.addEventListener(
'iceconnectionstatechange', handleConnectionChange);
remotePeerConnection.addEventListener('addstream', gotRemoteMediaStream);
// 添加本地流并创建连接
localPeerConnection.addStream(localStream);
console.log('Added local stream to localPeerConnection.');
console.log('localPeerConnection createOffer start.');
localPeerConnection.createOffer(offerOptions)
.then(createdOffer).catch(setSessionDescriptionError);
}
这里有一个需要注意的点,不知道hxd们知不知道,这里ICE并不是冰,他的意思是交互式连接建立,可以把他理解为是整合了 STUN 和 TURN的框架。
ICE用于确定可用于双端通信的传输地址对
再建立ice连接后,以event形式传输,从event中取出peerConnection对象和iceCandidate对象。
RTCIceCandidate用于描述WebRTC 能够与远程设备通信所需的协议和路由
function handleConnection(event) {
const peerConnection = event.target;
const iceCandidate = event.candidate;
if (iceCandidate) {
const newIceCandidate = new RTCIceCandidate(iceCandidate);
const otherPeer = getOtherPeer(peerConnection);
otherPeer.addIceCandidate(newIceCandidate)
.then(() => {}).catch((error) => {});
}
}