文档说明:只记录关键地方;2023-02-02
目标:熟悉WebRTC的使用
let begin = null;
let peerConnection=null;
// Parse the uint32 PRIORITY field into its constituent parts from RFC 5245,
// type preference, local preference, and (256 - component ID).
// ex: 126 | 32252 | 255 (126 is host preference, 255 is component ID 1)
function formatPriority(priority) {
return [
priority >> 24,
(priority >> 8) & 0xFFFF,
priority & 0xFF
].join(' | ');
}
function iceCallback(event) {
const elapsed = ((window.performance.now() - begin) / 1000).toFixed(3);
//console.log(event,event.candidate,RTCPeerConnection.prototype)
if (event.candidate) {
if (event.candidate.candidate === '') {
return;
}
const {candidate} = event;
console.log(
elapsed,
candidate.component,
candidate.type,
candidate.foundation,
candidate.protocol,
candidate.address,
candidate.port,
formatPriority(candidate.priority)
);
document.querySelector('.candidates').innerHTML +=`${candidate.type} ${candidate.protocol} ${candidate.address} ${candidate.port} <br/>`
} else if (!('onicegatheringstatechange' in RTCPeerConnection.prototype)) {
// should not be done if its done in the icegatheringstatechange callback.
}
}
function gatheringStateChange() {
console.log("iceGatheringState: "+peerConnection.iceGatheringState);
if (peerConnection.iceGatheringState === 'complete') {
const elapsed = ((window.performance.now() - begin) / 1000).toFixed(3);
console.log("iceGatheringState OK :"+elapsed,"ICE 准备好了,可以开始交换信令(SDP)了")
console.log("offer:", peerConnection.localDescription,peerConnection.localDescription.sdp)
}
}
function iceCandidateError(e) {
console.log(
'The server ' + e.url +
' returned an error with code=' + e.errorCode + ':\n' +
e.errorText + '\n'
)
// The interesting attributes of the error are
// * the url (which allows looking up the server)
// * the errorCode and errorText
}
(async () => {
//准备ICE
let configuration = {
iceServers: [
{
urls: ["stun:stun.freeswitch.org"]
},
],
iceCandidatePoolSize: 0
};
console.log(configuration)
peerConnection = new RTCPeerConnection(configuration);
console.log(peerConnection)
peerConnection.onicecandidate = iceCallback;
peerConnection.onicegatheringstatechange = gatheringStateChange;
peerConnection.onicecandidateerror = iceCandidateError;
peerConnection.ontrack = function (event) {
console.log(event);
/*
if (remote_video.srcObject !== event.streams[0]) {
remote_video.srcObject = event.streams[0];
}
*/
};
peerConnection.onsignalingstatechange = function (event) {
console.log(event, peerConnection.signalingState);
if (peerConnection.signalingState === "have-local-pranswer") {
// setLocalDescription() has been called with an answer
}
};
begin = window.performance.now();
const offer = await peerConnection.createOffer({
"offerToReceiveAudio": true,
"offerToReceiveVideo": true
});
await peerConnection.setLocalDescription(offer);
/*
await peerConnection.setRemoteDescription(payload.sender_sdp);
let answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
await peerConnection.setRemoteDescription(payload.sender_sdp);
*/
})()
参考文档
- webrtc.org
- WebRTC samples
- WebRTC samples GitHub repository
- available stun servers
- WebRTC可用性检测
- WebRTC三种类型(Mesh、MCU 和 SFU)的多方通信架构