File size: 2,141 Bytes
8709680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
const socket = io();

const urlParams = new URLSearchParams(window.location.search);
const roomId = urlParams.get("room");
const name = urlParams.get("name");

document.getElementById("roomTitle").innerText = "Room: " + roomId;

let localStream;
let peers = {};

async function start() {
  localStream = await navigator.mediaDevices.getUserMedia({ audio: true });

  socket.emit("join-room", { roomId, name });

  socket.on("all-users", (users) => {
    for (let id in users) {
      if (id !== socket.id) createPeer(id);
      addUser(users[id]);
    }
  });

  socket.on("user-joined", ({ id, name }) => {
    createPeer(id);
    addUser(name);
  });

  socket.on("signal", async ({ from, data }) => {
    if (!peers[from]) createPeer(from, false);

    if (data.sdp) {
      await peers[from].setRemoteDescription(data.sdp);
      if (data.sdp.type === "offer") {
        const answer = await peers[from].createAnswer();
        await peers[from].setLocalDescription(answer);
        socket.emit("signal", { to: from, data: { sdp: peers[from].localDescription } });
      }
    }

    if (data.candidate) {
      await peers[from].addIceCandidate(data.candidate);
    }
  });

  socket.on("user-left", (id) => {
    if (peers[id]) peers[id].close();
  });
}

function createPeer(id, initiator = true) {
  const peer = new RTCPeerConnection();

  localStream.getTracks().forEach(track => peer.addTrack(track, localStream));

  peer.onicecandidate = (e) => {
    if (e.candidate) {
      socket.emit("signal", {
        to: id,
        data: { candidate: e.candidate }
      });
    }
  };

  peer.ontrack = (e) => {
    const audio = document.createElement("audio");
    audio.srcObject = e.streams[0];
    audio.autoplay = true;
    document.body.appendChild(audio);
  };

  peers[id] = peer;

  if (initiator) {
    peer.createOffer().then(offer => {
      peer.setLocalDescription(offer);
      socket.emit("signal", { to: id, data: { sdp: offer } });
    });
  }
}

function addUser(name) {
  const div = document.createElement("div");
  div.innerText = "👤 " + name;
  document.getElementById("users").appendChild(div);
}

start();