RTCPeerConnection 接口代表一个由本地计算机到远端的WebRTC连接。该接口提供了创建,保持,监控,关闭连接的方法的实现。
一对一视频对话的时候,连接过程如下所示:
这个过程是不是看起来还挺清晰的?但是这只是表述了媒体信息交换的过程,别忘了还有网络信息~
接下来我们就先好好捋一捋PC建立的过程吧!
-
A打开本地视频流,创建PeerConnection对象,将本地音视频流封装成MediaStream添加到PeerConnection中;
-
A通过
CreateOffer
创建offer信息,调用setLocalDescription
储存本地offer,然后通过信令服务器将offer发送给B; -
A在调用
setLocalDescription
的同时,向服务器发送了iceCandidate消息; -
B打开本地视频流,创建PeerConnection对象,将本地音视频流封装成MediaStream添加到PeerConnection中;
-
B收到offer后,通过
setRemoteDescription
储存远端offer,然后通过CreateAnswer
创建answer信息,同样调用setLocalDescription
储存本地answer描述,再将answer发送给A; -
B在调用
setLocalDescription
的同时,向服务器发送了iceCandidate消息; -
A收到B的answer后,再次调用
setRemoteDescription
设置远端的answer描述。
那接下来就让我们从头看一看,一对一视频对话究竟是怎么实现的吧~ 这里我会按照事件的发送顺序,将客户端和服务器端的代码拆分开说,虽然从逻辑上来讲是对的,但是代码会比较乱,只用于理解,不能直接用哦。
当用户访问对话页面时,会向服务器发送’create or join’消息
服务器收到’create or join’,并计算当前房间里的人数
若 numClients === 0,则向客户端发送’created’消息;客户端收到’created’消息,则将当前用户作为会话发起人,令
isInitiator = true
。
若 numClients === 1, 则向会话发起人发送’join’消息,发起人端isChannelReady = true
; 向新用户发送’joined’消息,新用户端isChannelReady = true
,表示参与对话的两方都准备好了。
上面这一部分的代码在服务器的搭建中都讲过了。
客户端进入网页后会自动打开摄像头:
navigator.mediaDevices.getUserMedia({
audio: false,
video: true
})
.then(gotLocalMediaStream)
.catch(function (e) {
alert('getUserMedia() error: ' + e.name);
});
function gotLocalMediaStream(mediastream) {
console.log('Adding local stream.');
localStream = mediastream;
localVideo.srcObject = mediastream;
sendMessage('got user media');
if (isInitiator) {
maybeStart();
}
}
对于会话发起人,在打开摄像头的时候,会发起
maybeStart()
方法,进而实例化一个RTCPeerConnection,然后将本地的视频流加入pc中。
function maybeStart() {
console.log