110 lines
2.4 KiB
TypeScript
110 lines
2.4 KiB
TypeScript
class PeerManager {
|
|
connect(peerID: string) {
|
|
// Connect to the peer that has the peer id peerID
|
|
}
|
|
|
|
disconnect(peerID: string) {
|
|
}
|
|
}
|
|
|
|
class PeerConnection {
|
|
static config = {
|
|
iceServers: [
|
|
{ urls: "stun:stun.l.google.com" },
|
|
{ urls: "stun:stun1.l.google.com" },
|
|
{ urls: "stun:stun2.l.google.com" },
|
|
{ urls: "stun:stun3.l.google.com" },
|
|
{ urls: "stun:stun4.l.google.com" },
|
|
],
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
const config = {
|
|
iceServers: [{ urls: "stun:stun.mystunserver.tld" }],
|
|
};
|
|
|
|
let polite = true;
|
|
|
|
// const signaler = new SignalingChannel();
|
|
const signaler: any = {}
|
|
const pc = new RTCPeerConnection(config);
|
|
|
|
|
|
const constraints = { audio: true, video: true };
|
|
const selfVideo = document.querySelector("video.selfview");
|
|
const remoteVideo = document.querySelector("video.remoteview");
|
|
|
|
async function start() {
|
|
try {
|
|
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
|
|
for (const track of stream.getTracks()) {
|
|
pc.addTrack(track, stream);
|
|
}
|
|
// selfVideo.srcObject = stream;
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
|
|
pc.ontrack = ({ track, streams }) => {
|
|
track.onunmute = () => {
|
|
// if (remoteVideo.srcObject) {
|
|
// return;
|
|
// }
|
|
// remoteVideo.srcObject = streams[0];
|
|
};
|
|
};
|
|
|
|
let makingOffer = false;
|
|
|
|
pc.onnegotiationneeded = async () => {
|
|
try {
|
|
makingOffer = true;
|
|
await pc.setLocalDescription();
|
|
signaler.send({ description: pc.localDescription });
|
|
} catch (err) {
|
|
console.error(err);
|
|
} finally {
|
|
makingOffer = false;
|
|
}
|
|
};
|
|
|
|
pc.onicecandidate = ({ candidate }) => signaler.send({ candidate });
|
|
|
|
let ignoreOffer = false;
|
|
|
|
signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => {
|
|
try {
|
|
if (description) {
|
|
const offerCollision =
|
|
description.type === "offer" &&
|
|
(makingOffer || pc.signalingState !== "stable");
|
|
|
|
ignoreOffer = !polite && offerCollision;
|
|
if (ignoreOffer) {
|
|
return;
|
|
}
|
|
|
|
await pc.setRemoteDescription(description);
|
|
if (description.type === "offer") {
|
|
await pc.setLocalDescription();
|
|
signaler.send({ description: pc.localDescription });
|
|
}
|
|
} else if (candidate) {
|
|
try {
|
|
await pc.addIceCandidate(candidate);
|
|
} catch (err) {
|
|
if (!ignoreOffer) {
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}; |