]>
Commit | Line | Data |
---|---|---|
1 | import { io } from "socket.io-client"; | |
2 | import Peers from "./peers"; | |
3 | import Media from "./media"; | |
4 | ||
5 | const internals = { | |
6 | kSocketUrl: "https://junction.tranquil.services", | |
7 | kIceServers: [{ urls: "stun:stun.l.google.com:19302" }], | |
8 | ||
9 | port: null, | |
10 | socket: null, | |
11 | peers: {}, | |
12 | ||
13 | onMessage(message) { | |
14 | internals[message.action](message.data); | |
15 | }, | |
16 | ||
17 | async joinAudioCall({ currentUrl, tada }) { | |
18 | try { | |
19 | const mediaStream = await Media.start(); | |
20 | ||
21 | internals.socket = io(internals.kSocketUrl, { | |
22 | transports: ["websocket"], | |
23 | }); | |
24 | ||
25 | internals.socket.on("error", function (error) { | |
26 | console.error("GENERAL ERROR", error); | |
27 | }); | |
28 | ||
29 | internals.socket.on("connect_error", function (error) { | |
30 | console.error("CONNNECT ERROR", error); | |
31 | }); | |
32 | ||
33 | internals.socket.on("connect", function () { | |
34 | console.log("Connected to signaling server, group: ", currentUrl); | |
35 | internals.socket.emit("join", { | |
36 | room: currentUrl, | |
37 | }); | |
38 | }); | |
39 | ||
40 | internals.socket.on("disconnect", function () { | |
41 | console.log("disconnected from signaling server"); | |
42 | }); | |
43 | ||
44 | internals.socket.on("addPeer", function ({ peerId }) { | |
45 | /** | |
46 | * Eventually the whole rtc connection logic should be moved to Peers. | |
47 | * Now it only plays tadas. | |
48 | */ | |
49 | Peers.add(peerId, tada); | |
50 | ||
51 | const peerConnection = new RTCPeerConnection( | |
52 | { iceServers: internals.kIceServers }, | |
53 | { optional: [{ DtlsSrtpKeyAgreement: true }] }, | |
54 | ); | |
55 | ||
56 | internals.peers[peerId] = peerConnection; | |
57 | mediaStream.getTracks().forEach((track) => { | |
58 | peerConnection.addTrack(track, mediaStream); | |
59 | }); | |
60 | ||
61 | peerConnection.onicecandidate = (event) => { | |
62 | if (event.candidate) { | |
63 | internals.socket.emit("relayICECandidate", { | |
64 | peerId: peerId, | |
65 | candidate: event.candidate, | |
66 | }); | |
67 | } | |
68 | }; | |
69 | ||
70 | const remoteStream = new MediaStream(); | |
71 | peerConnection.ontrack = (event) => { | |
72 | remoteStream.addTrack(event.track); | |
73 | const remoteAudioElement = new Audio(); | |
74 | remoteAudioElement.srcObject = remoteStream; | |
75 | remoteAudioElement.play(); | |
76 | }; | |
77 | ||
78 | peerConnection.onnegotiationneeded = async () => { | |
79 | console.log("Creating RTC offer to ", peerId); | |
80 | const offer = await peerConnection.createOffer(); | |
81 | await peerConnection.setLocalDescription(offer); | |
82 | ||
83 | // Emit the offer to the peer | |
84 | internals.socket.emit("relayOffer", { offer, peerId }); | |
85 | }; | |
86 | ||
87 | console.log(`There are now ${Peers.count()} participants`); | |
88 | }); | |
89 | ||
90 | internals.socket.on("offerReceived", async ({ offer, peerId }) => { | |
91 | const peerConnection = internals.peers[peerId]; | |
92 | ||
93 | const remoteDescription = new RTCSessionDescription(offer); | |
94 | await peerConnection.setRemoteDescription(remoteDescription); | |
95 | ||
96 | const answer = await peerConnection.createAnswer(); | |
97 | await peerConnection.setLocalDescription(answer); | |
98 | ||
99 | // Send the answer to the peer | |
100 | internals.socket.emit("relayAnswer", { answer, peerId }); | |
101 | }); | |
102 | ||
103 | internals.socket.on("answerReceived", async ({ answer, peerId }) => { | |
104 | const peerConnection = internals.peers[peerId]; | |
105 | const remoteDescription = new RTCSessionDescription(answer); | |
106 | await peerConnection.setRemoteDescription(remoteDescription); | |
107 | }); | |
108 | ||
109 | internals.socket.on( | |
110 | "ICECandidateReceived", | |
111 | async ({ candidate, peerId }) => { | |
112 | const peerConnection = internals.peers[peerId]; | |
113 | const iceCandidate = new RTCIceCandidate(candidate); | |
114 | await peerConnection.addIceCandidate(iceCandidate); | |
115 | }, | |
116 | ); | |
117 | ||
118 | internals.socket.on("removePeer", function ({ peerId }) { | |
119 | delete internals.peers[peerId]; | |
120 | Peers.remove(peerId); | |
121 | console.log(`There are now ${Peers.count()} participants`); | |
122 | }); | |
123 | } catch (err) { | |
124 | internals.port.postMessage({ | |
125 | action: "error", | |
126 | }); | |
127 | internals.port.disconnect(); | |
128 | } | |
129 | }, | |
130 | ||
131 | hangUp() { | |
132 | Peers.reset(); | |
133 | Media.stop(); | |
134 | internals.socket.close(); | |
135 | internals.port.disconnect(); | |
136 | }, | |
137 | }; | |
138 | ||
139 | internals.port = chrome.runtime.connect({ name: "content" }); | |
140 | internals.port.onMessage.addListener(internals.onMessage); | |
141 | ||
142 | console.log("Content Script Loaded"); | |
143 | ||
144 | // Indicates to the background script that we executed correctly | |
145 | true; |