JSFiddle - React, Tailwind, and code Playground
by xdumaine
HTML
<button onclick="stopPc1()">
Stop PC1
</button>
<button onclick="stopPc2()">
Stop PC2
</button>
<hr/>
<video id="pc1" autoplay></video>
<video id="pc2" autoplay></video>
CSS
video {
height: 40px;
width: 60px;
}
JavaScript
let pc1, pc2;
(async function() {
pc1 = new RTCPeerConnection()
pc2 = new RTCPeerConnection()
// Log ice change events. Here you'd handle disconnects
icechange = (label, evt) =>
console.log(`${label} ICE ${evt.target.iceConnectionState}`)
pc1.oniceconnectionstatechange = icechange.bind(null, 'pc1')
pc2.oniceconnectionstatechange = icechange.bind(null, 'pc2')
// wire up ice candidates. Each candidate fires onicecandidate with a candidate,
// so take it and give it to the other connection via addIceCandidate
onicecandidate = (pc, e) => e.candidate && pc.addIceCandidate(e.candidate)
pc1.onicecandidate = onicecandidate.bind(null, pc2)
pc2.onicecandidate = onicecandidate.bind(null, pc1)
// wire up onaddstream events. when remote stream connects, the event will
// fire so you can attach the stream to the DOM
onaddstream = (sel, e) => {
console.log(`${sel} stream`, e)
document.getElementById(sel).srcObject = e.stream
}
pc1.onaddstream = onaddstream.bind(null, 'pc2')
pc2.onaddstream = onaddstream.bind(null, 'pc1')
// Get a stream and add it to the connections
const stream = navigator.mediaDevices.getUserMedia({
video: true,
audio: { autoGainControl: false, googAutoGainControl: false, googAutoGainControl2: false, googDucking: false }
})
stream.catch(err => console.error('Error getting media', err))
pc1.addStream(await stream)
pc2.addStream(await stream)
// The offerer creates an offer, setsLocalDescription, sends it to answerer
// Answerer sets the offer as the remoteDescription
// so user A localDescription === user B remoteDescription
const offer = pc1.createOffer()
offer.catch(err => console.error('Error creating offer', err))
pc1.setLocalDescription(await offer)
pc2.setRemoteDescription(await offer)
// The answerer creates an answer, does reverse of the offer flow
const answer = pc2.createAnswer();
answer.catch(err => console.error('Error creating answer', err))
...