本DEMO中,发送端和接收端都在本地,暂时省略了信令服务器
和真正的远端视频传输实现逻辑是一样的,只是缺少信令服务器,后续会加上,实现真正的端到端视频传输
let localVideo = document.querySelector('video#localvideo')
let remoteVideo = document.querySelector('video#remotevideo')
let btnStart = document.querySelector('button#start')
let btnCall = document.querySelector('button#call')
let btnHangup = document.querySelector('button#hangup')
let localStream
let pc1
let pc2
btnStart.onclick = () => {
if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
console.log('the getUserMedia is not supported!')
return
}else {
let constraints = {
video: true,
audio: true
}
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
localVideo.srcObject = stream
localStream = stream
})
.catch((err) => {
console.log(`Failed to get Media Stream! - ${err}`)
})
}
}
btnCall.onclick = () => {
// 创建两个连接 pc1 是调用者 pc2 是被调用者
pc2 = new RTCPeerConnection()
pc1 = new RTCPeerConnection()
// 收到候选者时触发的事件, 收到事件后交给对方,让对方插入自己的 candidate列表中
pc1.onicecandidate = (e) => {
pc2.addIceCandidate(e.candidate)
}
pc2.onicecandidate = (e) => {
pc1.addIceCandidate(e.candidate)
}
// 因为pc2是被调用者,当有数据时,它可以触发ontrack事件
pc2.ontrack = (e) => {
// 从streams中取第一个值,赋值给remoteVide,这样就可以显示远端的视频
remoteVideo.srcObject = e.streams[0]
}
// 将本地采集的流添加到pc1中
localStream.getTracks().forEach(track => {
pc1.addTrack(track, localStream)
});
let offerOptions = {
offerToRecieveAudio: 1,
offerToRecieveVideo: 1
}
// 媒体协商
pc1.createOffer(offerOptions)
.then((desc) => {
// desc.sdp 打印出来是offer的sdp信息
// 将desc放到自己远端的描述信息的槽
pc1.setLocalDescription(desc)
// send desc to signal 信令服务器
// receive desc from signal
pc2.setRemoteDescription(desc)
pc2.createAnswer()
.then((desc) => {
// desc.sdp 打印出来是answer的sdp信息
pc2.setLocalDescription(desc)
// send desc to signal
// receive desc from signal
pc1.setRemoteDescription(desc)
})
.catch((err) => {
console.log(`Failed to create answer! - ${err}`)
})
})
.catch((err) => {
console.log(`Failed to create offer! - ${err}`)
})
}
btnHangup.onclick = () => {
pc1.close()
pc2.close()
pc1 = null
pc2 = null
}
<html>
<head>
<title>PeerConnection</title>
</head>
<body>
<video id="localvideo" autoplay playsinline></video>
<video id="remotevideo" autoplay playsinline></video>
<div>
<button id="start">Start</button>
<button id="call">Call</button>
<button id="hangup">HangUp</button>
</div>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> -->
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="./js/client.js"></script>
</body>
</html>
实现效果

点击start,打开本地视频(左侧视频)
点击call,呼叫对端(右侧视频)
点击hangup,挂断对端(右侧视频)
网友评论