Files
chad/new-client/src/app/bootstrap/mediasoup.ts
2026-05-24 16:26:52 +06:00

139 lines
4.1 KiB
TypeScript

import { useMediasoup } from '@shared/composables/use-mediasoup'
import { useSignaling } from '@shared/composables/use-signaling'
import { Device } from 'mediasoup-client'
import { markRaw, watch } from 'vue'
const ICE_SERVERS: RTCIceServer[] = [
{ urls: 'stun:stunserver2025.stunprotocol.org:3478' },
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun.l.google.com:5349' },
{ urls: 'stun:stun1.l.google.com:3478' },
{ urls: 'stun:stun1.l.google.com:5349' },
{ urls: 'stun:stun2.l.google.com:19302' },
{ urls: 'stun:stun2.l.google.com:5349' },
{ urls: 'stun:stun3.l.google.com:3478' },
{ urls: 'stun:stun3.l.google.com:5349' },
{ urls: 'stun:stun4.l.google.com:19302' },
{ urls: 'stun:stun4.l.google.com:5349' },
]
export default function () {
const { socket } = useSignaling()
const ms = useMediasoup()
watch(socket, (socket) => {
if (!socket)
return
socket.on('initialized', async (initData) => {
ms.device.value = new Device()
await ms.device.value.load({ routerRtpCapabilities: initData.rtpCapabilities })
const sendInfo = await socket.emitWithAck('create-transport', { producing: true, consuming: false })
const sendTransport = ms.device.value.createSendTransport({
...sendInfo,
iceServers: [...ICE_SERVERS, ...(sendInfo.iceServers ?? [])],
})
ms.sendTransport.value = sendTransport
await ms.transports.add({
id: sendTransport.id,
ref: markRaw(sendTransport),
})
sendTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
try {
await socket.emitWithAck('connect-transport', { transportId: sendTransport.id, dtlsParameters })
callback()
}
catch (error) {
if (error instanceof Error)
errback(error)
}
})
sendTransport.on('produce', async ({ kind, rtpParameters, appData }, callback, errback) => {
try {
const { id } = await socket.emitWithAck('produce', {
transportId: sendTransport.id,
kind,
rtpParameters,
appData,
})
callback({ id })
}
catch (error) {
if (error instanceof Error)
errback(error)
}
})
const recvInfo = await socket.emitWithAck('create-transport', { producing: false, consuming: true })
const recvTransport = ms.device.value.createRecvTransport({
...recvInfo,
iceServers: [...ICE_SERVERS, ...(recvInfo.iceServers ?? [])],
})
ms.recvTransport.value = recvTransport
await ms.transports.add({
id: recvTransport.id,
ref: markRaw(recvTransport),
})
recvTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
try {
await socket.emitWithAck('connect-transport', { transportId: recvTransport.id, dtlsParameters })
callback()
}
catch (error) {
if (error instanceof Error)
errback(error)
}
})
})
socket.on('new-consumer', async ({ id, producerId, kind, rtpParameters, socketId, appData, producerPaused }, cb) => {
const rt = ms.recvTransport.value
if (!rt)
return
const consumer = await rt.consume({
id,
producerId,
kind,
rtpParameters,
streamId: `${socketId}-${appData.source ?? 'stream'}`,
appData: { ...appData, socketId },
})
if (producerPaused)
consumer.pause()
await ms.consumers.add({
id: consumer.id,
paused: consumer.paused,
kind: consumer.kind,
appData: consumer.appData as Record<string, unknown>,
track: consumer.track,
ref: markRaw(consumer),
})
cb()
})
socket.on('consumer-closed', ({ consumerId }) => {
ms.consumers.get(consumerId)?.ref.close()
})
socket.on('consumer-paused', ({ consumerId }) => {
ms.consumers.get(consumerId)?.ref.pause()
})
socket.on('consumer-resumed', ({ consumerId }) => {
ms.consumers.get(consumerId)?.ref.resume()
})
socket.on('disconnect', () => {
ms.clearAll()
})
}, { immediate: true })
}