X-Git-Url: https://git.r.bdr.sh/rbdr/junction/blobdiff_plain/80172072ed99b14e3d5b435b097888a4621f78bc..4a191e8036581893bf5f4cfb284770d1bfe9a807:/extension/peers.js diff --git a/extension/peers.js b/extension/peers.js index 51fd036..f9153fd 100644 --- a/extension/peers.js +++ b/extension/peers.js @@ -2,46 +2,92 @@ const internals = { peers: {}, createAudioElement(source) { + const audioElement = document.createElement("audio"); + audioElement.setAttribute("class", "junction-call-audio"); + audioElement.autoplay = "autoplay"; + audioElement.srcObject = source; - const audioElement = document.createElement('audio'); - audioElement.setAttribute('class', 'junction-call-audio'); - audioElement.autoplay = 'autoplay'; + document.querySelector("body").appendChild(audioElement); - // WE WILL NOT LOSE TADA SUPPORT - if (typeof source === 'string') { - audioElement.src = source; - } - else { - audioElement.srcObject = source; + return audioElement; + }, +}; + +export function addPeer({ peerId, mediaStream, onOffer, socket }) { + const peerConnection = new RTCPeerConnection( + { iceServers: internals.kIceServers }, + { optional: [{ DtlsSrtpKeyAgreement: true }] }, + ); + + internals.peers[peerId] = peerConnection; + mediaStream.getTracks().forEach((track) => { + peerConnection.addTrack(track, mediaStream); + }); + + peerConnection.onicecandidate = (event) => { + if (event.candidate) { + socket.emit("relayICECandidate", { + peerId: peerId, + candidate: event.candidate, + }); } + }; - document.querySelector('body').appendChild(audioElement); + const remoteStream = new MediaStream(); + peerConnection.ontrack = (event) => { + remoteStream.addTrack(event.track); + const remoteAudioElement = new Audio(); + remoteAudioElement.srcObject = remoteStream; + remoteAudioElement.play(); + }; - return audioElement; - } -}; + peerConnection.onnegotiationneeded = async () => { + console.debug("Creating RTC offer to ", peerId); + const offer = await peerConnection.createOffer(); + await peerConnection.setLocalDescription(offer); -export default { - add(id, source) { + onOffer({ peerId, offer }); + }; - internals.peers[id] && this.remove(id); - internals.peers[id] = internals.createAudioElement(source) - }, + console.info(`There are now ${countPeers()} participants`); +} - remove(id) { +export function removePeer({ peerId }) { + delete internals.peers[peerId]; + console.info(`There are now ${countPeers()} participants`); +} - internals.peers[id] && internals.peers[id].remove(); - delete internals.peers[id]; - }, +export async function answerPeerOffer({ peerId, offer }) { + const peerConnection = internals.peers[peerId]; - count() { + const remoteDescription = new RTCSessionDescription(offer); + await peerConnection.setRemoteDescription(remoteDescription); - return Object.keys(internals.peers).length; - }, + const answer = await peerConnection.createAnswer(); + await peerConnection.setLocalDescription(answer); - reset() { + return { peerId, answer }; +} - internals.peers = {}; - document.querySelectorAll('.junction-call-audio').forEach((audioElement) => audioElement.remove()); - } -}; +export async function processPeerAnswer({ peerId, answer }) { + const peerConnection = internals.peers[peerId]; + const remoteDescription = new RTCSessionDescription(answer); + await peerConnection.setRemoteDescription(remoteDescription); +} + +export async function addIceCandidate({ peerId, candidate }) { + const peerConnection = internals.peers[peerId]; + const iceCandidate = new RTCIceCandidate(candidate); + await peerConnection.addIceCandidate(iceCandidate); +} + +export function countPeers() { + return Object.keys(internals.peers).length; +} + +export function resetPeers() { + internals.peers = {}; + document + .querySelectorAll(".junction-call-audio") + .forEach((audioElement) => audioElement.remove()); +}