我正在尝试学习如何使用这个新酷的WebRTC API。
我遵循本教程https://simpl.info/rtcpeerconnection/,但我不明白如何从运行UV4L服务器的Raspberry Pi 3获取第二个流https://www.linux-projects.org/webrtc-signalling/
我已经使用websockets测试了UV4L内置WebRTC页面的功能,它可以正常工作。
到目前为止,这是我的代码,但它只在本地和远程视频标记中显示我的本地流两次。
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1" name="viewport">
<title>Peer connection</title>
</head>
<body>
<div id="container">
<video autoplay="" id="localVideo"></video> <video autoplay="" id="remoteVideo"></video>
<div>
<button id="startButton">Start</button> <button id="callButton">Call</button>
<button id="hangupButton">Hang Up</button>
</div>
</div>
<script src="js/main.js">
</script>
</body>
</html>
JavaScript的:
var startButton = document.getElementById('startButton');
var callButton = document.getElementById('callButton');
var hangupButton = document.getElementById('hangupButton');
callButton.disabled = true;
hangupButton.disabled = true;
startButton.onclick = start;
callButton.onclick = call;
hangupButton.onclick = hangup;
var startTime;
var localVideo = document.getElementById('localVideo');
var remoteVideo = document.getElementById('remoteVideo');
var localStream;
var pc1;
var pc2;
var offerOptions = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1,
};
function getName(pc) {
return pc === pc1 ? 'pc1' : 'pc2';
}
function getOtherPc(pc) {
return pc === pc1 ? pc2 : pc1;
}
function gotStream(stream) {
localVideo.srcObject = stream;
localStream = stream;
callButton.disabled = false;
}
function start() {
startButton.disabled = true;
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
})
.then(gotStream)
.catch(function(e) {
alert('getUserMedia() error: ' + e.name);
});
}
function call() {
callButton.disabled = true;
hangupButton.disabled = false;
startTime = window.performance.now();
var videoTracks = localStream.getVideoTracks();
var audioTracks = localStream.getAudioTracks();
// MY UV4L stun server
var servers = {
iceServers: [ { urls: [ 'stun:' + '192.84.178.59' + ':3478' ] } ],
};
pc1 = new RTCPeerConnection(servers);
pc1.onicecandidate = function(e) {
onIceCandidate(pc1, e);
};
console.log(servers);
pc2 = new RTCPeerConnection(servers);
pc2.onicecandidate = function(e) {
onIceCandidate(pc2, e);
};
pc1.oniceconnectionstatechange = function(e) {
onIceStateChange(pc1, e);
};
pc2.oniceconnectionstatechange = function(e) {
onIceStateChange(pc2, e);
};
pc2.ontrack = gotRemoteStream;
localStream.getTracks().forEach(function(track) {
pc1.addTrack(track, localStream);
});
pc1.createOffer(offerOptions).then(onCreateOfferSuccess, onCreateSessionDescriptionError);
}
function onCreateSessionDescriptionError(error) {
console.log(error.toString());
}
function onCreateOfferSuccess(desc) {
pc1.setLocalDescription(desc).then(function() {
onSetLocalSuccess(pc1);
}, onSetSessionDescriptionError);
pc2.setRemoteDescription(desc).then(function() {
onSetRemoteSuccess(pc2);
}, onSetSessionDescriptionError);
pc2.createAnswer().then(onCreateAnswerSuccess, onCreateSessionDescriptionError);
}
function onSetLocalSuccess(pc) {
console.log(getName(pc) + ' setLocalDescription complete');
}
function onSetRemoteSuccess(pc) {
console.log(getName(pc) + ' setRemoteDescription complete');
}
function onSetSessionDescriptionError(error) {
console.log('Failed to set session description: ' + error.toString());
}
function gotRemoteStream(e) {
if (remoteVideo.srcObject !== e.streams[0]) {
console.log(e.streams[0]);
remoteVideo.srcObject = e.streams[0];
}
}
function onCreateAnswerSuccess(desc) {
pc2.setLocalDescription(desc).then(function() {
onSetLocalSuccess(pc2);
}, onSetSessionDescriptionError);
pc1.setRemoteDescription(desc).then(function() {
onSetRemoteSuccess(pc1);
}, onSetSessionDescriptionError);
}
function onIceCandidate(pc, event) {
getOtherPc(pc).addIceCandidate(event.candidate).then(
function() {
onAddIceCandidateSuccess(pc);
},
function(err) {
onAddIceCandidateError(pc, err);
},
);
}
function onAddIceCandidateSuccess(pc) {
console.log(getName(pc) + ' addIceCandidate success');
}
function onAddIceCandidateError(pc, error) {
console.log(getName(pc) + ' failed to add ICE Candidate: ' + error.toString());
}
function onIceStateChange(pc, event) {
if (pc) {
console.log(getName(pc) + ' ICE state: ' + pc.iceConnectionState);
console.log('ICE state change event: ', event);
}
}
function hangup() {
pc1.close();
pc2.close();
pc1 = null;
pc2 = null;
hangupButton.disabled = true;
callButton.disabled = false;
}