Files
commandcenter-websource/src/lib/connect.ts
2023-12-01 11:03:24 +01:00

99 lines
2.7 KiB
TypeScript

export async function PeerConnection(media: string) {
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
})
const localTracks = []
if (/camera|microphone/.test(media)) {
const tracks = await getMediaTracks('user', {
video: media.indexOf('camera') >= 0,
audio: media.indexOf('microphone') >= 0,
})
tracks.forEach((track) => {
pc.addTransceiver(track, { direction: 'sendonly' })
if (track.kind === 'video') localTracks.push(track)
})
}
if (media.indexOf('display') >= 0) {
const tracks = await getMediaTracks('display', {
video: true,
audio: media.indexOf('speaker') >= 0,
})
tracks.forEach((track) => {
pc.addTransceiver(track, { direction: 'sendonly' })
if (track.kind === 'video') localTracks.push(track)
})
}
if (/video|audio/.test(media)) {
const tracks = ['video', 'audio']
.filter((kind) => media.indexOf(kind) >= 0)
.map((kind) => pc.addTransceiver(kind, { direction: 'recvonly' }).receiver.track)
localTracks.push(...tracks)
}
return { pc, localTracks }
}
export async function getMediaTracks(media: string, constraints?: MediaStreamConstraints) {
try {
const stream =
media === 'user'
? await navigator.mediaDevices.getUserMedia(constraints)
: await navigator.mediaDevices.getDisplayMedia(constraints)
return stream.getTracks()
} catch (e) {
console.warn(e)
return []
}
}
export async function connect(url: string, media: string) {
const { pc, localTracks } = await PeerConnection(media)
let ws = new WebSocket('ws' + url.toString().substring(4))
ws.onopen = function () {
pc.addEventListener('icecandidate', (ev) => {
if (!ev.candidate) return
const msg = { type: 'webrtc/candidate', value: ev.candidate.candidate }
ws.send(JSON.stringify(msg))
})
pc.createOffer()
.then((offer) => pc.setLocalDescription(offer))
.then(() => {
const msg = { type: 'webrtc/offer', value: pc.localDescription?.sdp }
ws.send(JSON.stringify(msg))
})
}
ws.onmessage = function (ev) {
const msg = JSON.parse(ev.data)
if (msg.type === 'webrtc/candidate') {
pc.addIceCandidate({ candidate: msg.value, sdpMid: '0' })
} else if (msg.type === 'webrtc/answer') {
pc.setRemoteDescription({ type: 'answer', sdp: msg.value })
}
}
ws.onerror = function (ev) {
console.log({ ev })
}
ws.onclose = function () {
setTimeout(function () {
var ws2 = new WebSocket(ws.url)
ws2.onopen = ws.onopen
ws2.onmessage = ws.onmessage
ws2.onclose = ws.onclose
ws2.onerror = ws.onerror
ws = ws2
}, 2000)
}
return new MediaStream(localTracks)
}