From c365f3e88514af598b4ddc188d2bd5f43078d4b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9A=D1=80=D1=83?= =?UTF-8?q?=D0=B3=D0=BB=D0=B8=D1=86=D0=BA=D0=B8=D0=B9?= Date: Fri, 3 Oct 2025 02:36:38 +0600 Subject: [PATCH] #4 --- client/app/composables/use-mediasoup.ts | 33 +++++++++++++++++-------- client/eslint.config.mjs | 3 +++ server/sockets/webrtc.ts | 10 +++++--- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/client/app/composables/use-mediasoup.ts b/client/app/composables/use-mediasoup.ts index b262a26..f0f45b0 100644 --- a/client/app/composables/use-mediasoup.ts +++ b/client/app/composables/use-mediasoup.ts @@ -1,3 +1,4 @@ +import type { type Consumer, Producer } from 'mediasoup-client/types' import type { Socket } from 'socket.io-client' import { createGlobalState } from '@vueuse/core' import * as mediasoupClient from 'mediasoup-client' @@ -24,7 +25,7 @@ export const useMediasoup = createGlobalState(() => { const initializing = ref(false) const connected = ref(false) - const streams = shallowRef([]) + const streams = shallowRef>({}) let device: mediasoupClient.Device let sendTransport: mediasoupClient.types.Transport let recvTransport: mediasoupClient.types.Transport @@ -44,6 +45,12 @@ export const useMediasoup = createGlobalState(() => { await consume(producerId) }) + socket.on('producerClosed', async (producerId: Producer['id']) => { + delete streams.value[producerId] + + triggerRef(streams) + }) + async function consume(producerId: number) { const params = await socket.emitWithAck('consume', { producerId, @@ -60,9 +67,11 @@ export const useMediasoup = createGlobalState(() => { ...params, id: params.consumerId, }) + const stream = new MediaStream([consumer.track]) - streams.value.push(stream) + streams.value[producerId] = stream + triggerRef(streams) } @@ -91,8 +100,10 @@ export const useMediasoup = createGlobalState(() => { callback() } - catch (err) { - errback(err) + catch (error) { + if (error instanceof Error) { + errback(error) + } } }) @@ -105,8 +116,10 @@ export const useMediasoup = createGlobalState(() => { }) callback({ id: producerId }) } - catch (err) { - errback(err) + catch (error) { + if (error instanceof Error) { + errback(error) + } } }) } @@ -116,12 +129,10 @@ export const useMediasoup = createGlobalState(() => { console.log(devices) const stream = await navigator.mediaDevices.getUserMedia({ - // audio: true, audio: { autoGainControl: false, noiseSuppression: true, echoCancellation: false, - latency: 0, }, }) const track = stream.getAudioTracks()[0] @@ -148,8 +159,10 @@ export const useMediasoup = createGlobalState(() => { callback() } - catch (err) { - errback(err) + catch (error) { + if (error instanceof Error) { + errback(error) + } } }) } diff --git a/client/eslint.config.mjs b/client/eslint.config.mjs index a5d5081..6fe4bb3 100644 --- a/client/eslint.config.mjs +++ b/client/eslint.config.mjs @@ -5,6 +5,9 @@ export default antfu({ css: true, }, overrides: { + typescript: { + 'no-console': 'off', + }, vue: { 'vue/block-order': ['error', { order: ['template', 'script', 'style'], diff --git a/server/sockets/webrtc.ts b/server/sockets/webrtc.ts index 924edec..b77673b 100644 --- a/server/sockets/webrtc.ts +++ b/server/sockets/webrtc.ts @@ -57,6 +57,7 @@ interface ClientToServerEvents extends Record { interface ServerToClientEvents { producers: (arg: ProducerShort[]) => void newProducer: (arg: ProducerShort) => void + producerClosed: (arg: types.Producer['id']) => void } const transports = new Map() @@ -167,7 +168,8 @@ export default function (io: SocketServer, router: types.Router) { cb({ producerId: producer.id }) socket.broadcast.emit('newProducer', { producerId: producer.id, kind: producer.kind }) - producer.observer.on('close', () => { + producer.on('transportclose', () => { + socket.broadcast.emit('producerClosed', producer.id) consola.log('[WebRtc]', 'Producer closed', producer.id) }) } @@ -223,9 +225,9 @@ export default function (io: SocketServer, router: types.Router) { socket.on('disconnect', () => { consola.info('Client disconnected:', socket.id) - transports.get(socket.id)?.forEach(t => t.close()) - producers.get(socket.id)?.forEach(p => p.close()) - consumers.get(socket.id)?.forEach(c => c.close()) + transports.get(socket.id)!.forEach(t => t.close()) + producers.get(socket.id)!.forEach(p => p.close()) + consumers.get(socket.id)!.forEach(c => c.close()) transports.delete(socket.id) producers.delete(socket.id)