本文分享的这个流程里只包含了1对1的通信流程,暂未涉及TURN跟STUN,后续补上。
通信流程
首先是对传输内容的获取,采用浏览器的接口方法可以获取到用户的一个显示界面或是指定的显示程序或者用户摄像设备,可根据相应的配置参数对采集的数据进行设置,包括音视频信息、编码参数等。
opencam () {
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
var self = this
// 这里可以通过getUserMedia 获取视频设备
navigator.mediaDevices.getDisplayMedia({video: true, audio: false}).then((stream) => {
self.dojoin()
self.video_stream = stream
self.$refs.video.srcObject = stream
self.$refs.video.play()
}).catch(err => {
console.log('media error:' + err)
})
},
双向通信中,需要一个信令服务器来完成双向的信息交互,可以用标准的API服务器,也可以用websocket服务器,本地示例以websocket为例。
Webrtc具体流程如下:
1:客户端A将用户信息发送到信令服务器,并保存到服务器中
2:客户端B将信息发送到信令服务器后,服务器会将客户端B的信息发送到客户端A
3:A在接收到有其它用户登录的情况下,创建一个RTCPeerConnection对象,并监听onicecandidate跟ontrack回调,同时本地的流媒体信息写入到RTCPeerConnection中。
this.pc = new RTCPeerConnection(null)
this.pc.onicecandidate = this.handleIceCandidate
this.pc.ontrack = this.handleTrack
this.video_stream.getTracks().forEach((track) => {
this.pc.addTrack(track, this.video_stream)
})
4:A创建一个offer,并写入localDescription,同时将offer信息经信令服务器转发给B。
5:B在收到A的offer后,同样创建一个RTCPeerConnection对象,跟步骤3操作一样,将写A的offer设置到本地的remoteDescription并创建answer。将answer写入到localDescription后,会将answer经服务器传到A。
// 【包含流程5、6】
handleOffer (message) {
// 接收到服务器端转到的offer数据
// 这里需要保存到本地,同时本地创建一个answer数据,并回传给到主播端
console.log('get offer')
if (this.pc == null) {
this.createPeerConnection()
}
var desc = JSON.parse(message.msg)
this.pc.setRemoteDescription(desc)
this.doAnswer()
},
doAnswer () {
this.pc.createAnswer().then(this.createAnswerAndSend).catch(this.createAnswerFailed)
},
createAnswerAndSend (session) {
console.log('send answer')
this.pc.setLocalDescription(session)
.then(function () {
var msg = {
'cmd': 'answer',
'username': this.remoteuUserName,
'msg': JSON.stringify(session)
}
this.sock.send(JSON.stringify(msg))
console.log('createAnswerAndSend sucess!~' + this.username + '|' + this.remoteuUserName)
})
.catch((e) => {
console.log('set localDiscription fialed!' + e)
})
},
createAnswerFailed (e) {
console.log('createAnswerFailed:' + e)
},
6:A在收到answer消息后,将其写入romoteDescription。完成双方的offer/answer信息的互换。
7:A、B机器在创建RTCPeerConnection对象后,其onicecandidate回调获取网络信息,双方分别将信息经由信令服务器转发到对方。
//【包含流程7、8】
handleIceCandidate (event) {
if (event.candidate) {
console.log('发送Candidata到中转服务器:' + JSON.stringify(event.candidate))
var message = {
'cmd': 'candidate',
'username': this.username,
'msg': JSON.stringify(event.candidate)
}
this.sock.send(JSON.stringify(message))
}
},
handleTrack (event) {
console.log('get handleTrack')
/**
* 拿到远程数据时,就把远程数据绑定到本地的某个显示对象上去
*/
console.log('handleTrack:' + JSON.stringify(event))
this.remoteStream = event.streams[0]
this.$refs.remote.srcObject = this.remoteStream
this.$refs.remote.play()
},
8:A、B机器的RTCPeerConnection对象,其ontrack分别接收到对方的stream,即对方的视频信息,将其绑定显示对象上,即可获取对方的影响(这里的表述可能有些问题,但效果是可以正常运行的)
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。