import { io } from 'socket.io-client'; import Peers from './peers'; import Media from './media'; const internals = { kSocketUrl: 'https://junction.tranquil.services', kIceServers: [ {url:"stun:stun.l.google.com:19302"} ], port: null, socket: null, peers: {}, onMessage(message) { internals[message.action](message.data); }, async joinAudioCall(data) { internals.tada = data.tada; // Keeping for fun try { const mediaStream = await Media.start(); internals.socket = io(internals.kSocketUrl, { transports: ['websocket'] }); internals.socket.on('error', function(error) { console.error('GENERAL ERROR', error); }); internals.socket.on('connect_error', function(error) { console.error('CONNNECT ERROR', error); }); internals.socket.on('connect', function() { console.log('Connected to signaling server, group: ', data.currentUrl); internals.socket.emit('join', { room: data.currentUrl, }); }); internals.socket.on('disconnect', function() { console.log("disconnected from signaling server"); }); internals.socket.on('addPeer', function(data) { Peers.add(data.peerId, internals.tada); const peerId = data.peerId; const peerConnection = new RTCPeerConnection( { iceServers: internals.kIceServers }, { optional: [{ DtlsSrtpKeyAgreement: true }] } ); internals.peers[peerId] = peerConnection; mediaStream.getTracks().forEach((track) => { peerConnection.addTrack(track, localStream); }); peerConnection.onicecandidate = (event) => { if (event.candidate) { internals.socket.emit('relayICECandidate', { peerId: peerId, candidate: event.candidate }); } } const remoteStream = new MediaStream(); peerConnection.ontrack = (event) => { remoteStream.addTrack(event.track); const remoteAudioElement = new Audio(); remoteAudioElement.srcObject = remoteStream; remoteAudioElement.play(); }; peerConnection.onnegotiationneeded = async () => { console.log("Creating RTC offer to ", peerId); const offer = await peerConnection.createOffer(); await peerConnection.setLocalDescription(offer); // Emit the offer to the peer socket.emit('relayOffer', { offer, peerId }); }; console.log(`There are now ${Peers.count()} participants`); }); socket.on('offerReceived', async (data) => { const peerConnection = internals.peers[data.peerId]; const offer = new RTCSessionDescription(data.offer); await peerConnection.setRemoteDescription(offer); const answer = await peerConnection.createAnswer(); await peerConnection.setLocalDescription(answer); // Send the answer to the peer socket.emit('relayAnswer', { answer, peerId: data.peerId }); }); socket.on('answerReceived', async (data) => { const peerConnection = internals.peers[data.peerId]; const answer = new RTCSessionDescription(data.answer); await peerConnection.setRemoteDescription(answer); }); socket.on('ICECandidateReceived', async (data) => { const peerConnection = internals.peers[data.peerId]; const candidate = new RTCIceCandidate(data.candidate); await peerConnection.addIceCandidate(candidate); }); internals.socket.on('removePeer', function() { delete internals.peers[data.peerId]; Peers.remove('id-'+(Peers.count() - 1)); // This is only for testing, don't use count to remove ids. console.log(`There are now ${Peers.count()} participants`); }); } catch (err) { internals.port.postMessage({ action: 'error' }); internals.port.disconnect(); } }, hangUp() { Peers.reset(); Media.stop(); internals.socket.close(); internals.port.disconnect(); } }; internals.port = chrome.runtime.connect({ name:"content" }); internals.port.onMessage.addListener(internals.onMessage); console.log('Content Script Loaded'); // Indicates to the background script that we executed correctly true;