]>
Commit | Line | Data |
---|---|---|
e2da0c51 RBR |
1 | const internals = { |
2 | peers: {}, | |
3 | ||
4 | createAudioElement(source) { | |
b9a2baf2 RBR |
5 | const audioElement = document.createElement("audio"); |
6 | audioElement.setAttribute("class", "junction-call-audio"); | |
7 | audioElement.autoplay = "autoplay"; | |
06b7617a | 8 | audioElement.srcObject = source; |
d38261f1 | 9 | |
b9a2baf2 | 10 | document.querySelector("body").appendChild(audioElement); |
e2da0c51 RBR |
11 | |
12 | return audioElement; | |
b9a2baf2 | 13 | }, |
e2da0c51 RBR |
14 | }; |
15 | ||
3f2e36ea | 16 | export function addPeer({ peerId, shouldCreateOffer, mediaStream, onOffer, socket }) { |
06b7617a RBR |
17 | const peerConnection = new RTCPeerConnection( |
18 | { iceServers: internals.kIceServers }, | |
19 | { optional: [{ DtlsSrtpKeyAgreement: true }] }, | |
20 | ); | |
e2da0c51 | 21 | |
06b7617a RBR |
22 | internals.peers[peerId] = peerConnection; |
23 | mediaStream.getTracks().forEach((track) => { | |
24 | peerConnection.addTrack(track, mediaStream); | |
25 | }); | |
e2da0c51 | 26 | |
06b7617a RBR |
27 | peerConnection.onicecandidate = (event) => { |
28 | if (event.candidate) { | |
29 | socket.emit("relayICECandidate", { | |
30 | peerId: peerId, | |
31 | candidate: event.candidate, | |
32 | }); | |
33 | } | |
34 | }; | |
e2da0c51 | 35 | |
06b7617a RBR |
36 | const remoteStream = new MediaStream(); |
37 | peerConnection.ontrack = (event) => { | |
38 | remoteStream.addTrack(event.track); | |
39 | const remoteAudioElement = new Audio(); | |
40 | remoteAudioElement.srcObject = remoteStream; | |
41 | remoteAudioElement.play(); | |
42 | }; | |
43 | ||
44 | peerConnection.onnegotiationneeded = async () => { | |
3f2e36ea RBR |
45 | if (shouldCreateOffer) { |
46 | console.debug("Creating RTC offer to ", peerId); | |
47 | const offer = await peerConnection.createOffer(); | |
48 | await peerConnection.setLocalDescription(offer); | |
06b7617a | 49 | |
3f2e36ea RBR |
50 | onOffer({ peerId, offer }); |
51 | } | |
06b7617a RBR |
52 | }; |
53 | ||
54 | console.info(`There are now ${countPeers()} participants`); | |
55 | } | |
56 | ||
57 | export function removePeer({ peerId }) { | |
58 | delete internals.peers[peerId]; | |
59 | console.info(`There are now ${countPeers()} participants`); | |
60 | } | |
61 | ||
62 | export async function answerPeerOffer({ peerId, offer }) { | |
3f2e36ea | 63 | console.info(`Answering peer ${peerId}`); |
06b7617a RBR |
64 | const peerConnection = internals.peers[peerId]; |
65 | ||
66 | const remoteDescription = new RTCSessionDescription(offer); | |
67 | await peerConnection.setRemoteDescription(remoteDescription); | |
68 | ||
69 | const answer = await peerConnection.createAnswer(); | |
70 | await peerConnection.setLocalDescription(answer); | |
71 | ||
72 | return { peerId, answer }; | |
73 | } | |
74 | ||
75 | export async function processPeerAnswer({ peerId, answer }) { | |
3f2e36ea | 76 | console.info(`Processing answer for peer ${peerId}`); |
06b7617a RBR |
77 | const peerConnection = internals.peers[peerId]; |
78 | const remoteDescription = new RTCSessionDescription(answer); | |
79 | await peerConnection.setRemoteDescription(remoteDescription); | |
80 | } | |
81 | ||
82 | export async function addIceCandidate({ peerId, candidate }) { | |
3f2e36ea | 83 | console.info(`Adding ICE candidate for peer ${peerId}`); |
06b7617a | 84 | const peerConnection = internals.peers[peerId]; |
3f2e36ea | 85 | console.info(peerConnection.signalingState); |
06b7617a RBR |
86 | const iceCandidate = new RTCIceCandidate(candidate); |
87 | await peerConnection.addIceCandidate(iceCandidate); | |
88 | } | |
89 | ||
90 | export function countPeers() { | |
91 | return Object.keys(internals.peers).length; | |
92 | } | |
93 | ||
94 | export function resetPeers() { | |
95 | internals.peers = {}; | |
96 | document | |
97 | .querySelectorAll(".junction-call-audio") | |
98 | .forEach((audioElement) => audioElement.remove()); | |
99 | } |