this repo has no description
1const ICE_SERVERS = [{ urls: "stun:stun.l.google.com:19302" }];
2
3/**
4 * @param {(event: RTCTrackEvent) => void} onTrack
5 * @returns {RTCPeerConnection}
6 */
7export function createPeerConnection(onTrack) {
8 const pc = new RTCPeerConnection({ iceServers: ICE_SERVERS });
9 pc.ontrack = onTrack;
10 return pc;
11}
12
13/** @param {RTCPeerConnection} pc */
14function gatherComplete(pc) {
15 return new Promise((resolve) => {
16 if (pc.iceGatheringState === "complete") return resolve();
17 const onChange = () => {
18 if (pc.iceGatheringState === "complete") {
19 pc.removeEventListener("icegatheringstatechange", onChange);
20 resolve();
21 }
22 };
23 pc.addEventListener("icegatheringstatechange", onChange);
24 // timeout after 10s — use whatever candidates we have
25 setTimeout(() => {
26 pc.removeEventListener("icegatheringstatechange", onChange);
27 resolve();
28 }, 10000);
29 });
30}
31
32/**
33 * @param {RTCPeerConnection} pc
34 * @param {MediaStream} stream
35 * @returns {Promise<string>} SDP with all ICE candidates
36 */
37export async function createOffer(pc, stream) {
38 for (const track of stream.getTracks()) pc.addTrack(track, stream);
39 const offer = await pc.createOffer();
40 await pc.setLocalDescription(offer);
41 await gatherComplete(pc);
42 return pc.localDescription.sdp;
43}
44
45/**
46 * @param {RTCPeerConnection} pc
47 * @param {MediaStream} stream
48 * @param {string} remoteSdp
49 * @returns {Promise<string>} SDP with all ICE candidates
50 */
51export async function createAnswer(pc, stream, remoteSdp) {
52 for (const track of stream.getTracks()) pc.addTrack(track, stream);
53 await pc.setRemoteDescription(new RTCSessionDescription({ type: "offer", sdp: remoteSdp }));
54 const answer = await pc.createAnswer();
55 await pc.setLocalDescription(answer);
56 await gatherComplete(pc);
57 return pc.localDescription.sdp;
58}