本机内的1:1音视频互通
- 获取媒体信息
function start(){
if (!navigator.mediaDevices||
!navigator.mediaDevices.getUserMedia) {
console.error('the getUserMedia is not supported!');
return;
} else {
var constraints={
video:true,
audio:true
}
navigator.mediaDevices.getUserMedia(constraints)
.then(getMediaStream)
.catch(handleError)
}
}
这里和前面一样,getUserMedia获取摄像头信息,constraints配置参数
- 本地媒体流显示到localVideo
function getMediaStream(stream){
localVideo.srcObject=stream;
localStream=stream;
}
- 创建媒体协商
function call(){
pc1 = new RTCPeerConnection();
pc2 = new RTCPeerConnection();
pc1.onicecandidate=(e)=>{
pc2.addIceCandidate(e.candidate);
}
pc2.onicecandidate=(e)=>{
pc1.addIceCandidate(e.candidate);
}
pc2.ontrack=getRemoteStream;
localStream.getTracks().forEach((track)=>{
pc1.addTrack(track,localStream);
});
var offerOptions={
offerToRecieveAudio:1,
offerToRecieveVideo:1
}
pc1.createOffer(offerOptions)
.then(getOffer)
.catch(handleOfferError);
}
//本地媒体流显示到remoteVideo
function getRemoteStream(e){
remoteVideo.srcObject = e.streams[0];
}
- 将sdp写入本地1和本地2并创建访问
function getOffer(desc){
pc1.setLocalDescription(desc);
pc2.setRemoteDescription(desc);
pc2.createAnswer()
.then(getAnswer)
.catch(handleAnswerError);
}
- 将sdp写入本地1和本地2并创建回答
function getAnswer(desc){
pc2.setLocalDescription(desc);
pc1.setRemoteDescription(desc);
}
- 挂断
function hangup(){
pc1.close();
pc2.close();
pc1 = null;
pc2 = null;
}
效果
获取 offer/answer 创建的 SDP
function getAnswer(desc){
...
answer.value=desc.sdp;
...
}
function getOffer(desc){
...
offer.value=desc.sdp;
...
}
全部代码
- html
<html>
<head>
<title>WebRtc peerConnection</title>
<style>
.local,
.remote{
display: flex;
}
.textarea{
margin-left: 20px;
}
textarea{
width: 500px;
height: 600px;
}
</style>
</head>
<body>
<div>
<div class="local">
<div>
<h2>Local:</h2>
<video id="localvideo" autoplay playsinline></video>
</div>
<div class="textarea">
<h2>Offer SDP:</h2>
<textarea id="offer"></textarea>
</div>
</div>
<div class="remote">
<div>
<h2>Remote:</h2>
<video id="remotevideo" autoplay playsinline></video>
</div>
<div class="textarea">
<h2>Answer SDP:</h2>
<textarea id="answer"></textarea>
</div>
</div>
<div>
<button id="start">Start</button>
<button id="call">Call</button>
<button id="hangup">HangUp</button>
</div>
</div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
- js
'use strict'
var localVideo = document.querySelector('video#localvideo');
var remoteVideo = document.querySelector('video#remotevideo');
var btnStart = document.querySelector('button#start');
var btnCall = document.querySelector('button#call');
var btnHangup = document.querySelector('button#hangup');
var offer = document.querySelector('textarea#offer');
var answer = document.querySelector('textarea#answer');
var localStream;
var pc1;
var pc2;
function getMediaStream(stream){
localVideo.srcObject=stream;
localStream=stream;
}
function handleError(err){
console.error('failed to get media Stream!,',err);
}
function start(){
if (!navigator.mediaDevices||
!navigator.mediaDevices.getUserMedia) {
console.error('the getUserMedia is not supported!');
return;
} else {
var constraints={
video:true,
audio:true
}
navigator.mediaDevices.getUserMedia(constraints)
.then(getMediaStream)
.catch(handleError)
}
}
function handleOfferError(err){
console.err("Failed to create offer: ",err);
}
function handleAnswerError(err){
console.err("Failed to create answer: ",err);
}
function getAnswer(desc){
pc2.setLocalDescription(desc);
answer.value=desc.sdp;
pc1.setRemoteDescription(desc);
}
function getOffer(desc){
pc1.setLocalDescription(desc);
offer.value=desc.sdp;
pc2.setRemoteDescription(desc);
pc2.createAnswer()
.then(getAnswer)
.catch(handleAnswerError);
}
function getRemoteStream(e){
remoteVideo.srcObject = e.streams[0];
}
function call(){
pc1 = new RTCPeerConnection();
pc2 = new RTCPeerConnection();
pc1.onicecandidate=(e)=>{
pc2.addIceCandidate(e.candidate);
}
pc2.onicecandidate=(e)=>{
pc1.addIceCandidate(e.candidate);
}
pc2.ontrack=getRemoteStream;
localStream.getTracks().forEach((track)=>{
pc1.addTrack(track,localStream);
});
var offerOptions={
offerToRecieveAudio:1,
offerToRecieveVideo:1
}
pc1.createOffer(offerOptions)
.then(getOffer)
.catch(handleOfferError);
}
function hangup(){
pc1.close();
pc2.close();
pc1 = null;
pc2 = null;
}
btnStart.onclick=start;
btnCall.onclick=call;
btnHangup.onclick=hangup;
测试地址:https://www.huangxiaoguo.club/peerconnection/index.html