This commit is contained in:
2023-04-20 12:05:32 +02:00
commit 9975bbb42c
30 changed files with 11480 additions and 0 deletions

85
src/lib/connect.ts Normal file
View File

@@ -0,0 +1,85 @@
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)
// document.getElementById(videoId).srcObject = new MediaStream(localTracks)
const ws = new WebSocket('ws' + url.toString().substring(4))
ws.addEventListener('open', () => {
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.addEventListener('message', (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 })
}
})
return new MediaStream(localTracks)
}