Files
chad/new-client/src/shared/composables/use-mediasoup.ts
2026-05-22 05:08:41 +06:00

120 lines
3.1 KiB
TypeScript

import type { Consumer, Device, Producer, Transport } from 'mediasoup-client/types'
import type { Ref } from 'vue'
import { createEventHook, createGlobalState } from '@vueuse/core'
import { computed, ref, shallowRef } from 'vue'
interface Snapshot<T> {
id: string
ref: T
[key: string]: any
}
export interface ProducerSnapshot extends Snapshot<Producer> {
paused: boolean
kind: string
appData: Record<string, unknown>
}
export interface ConsumerSnapshot extends Snapshot<Consumer> {
paused: boolean
kind: string
appData: Record<string, unknown>
track: MediaStreamTrack
}
export interface TransportSnapshot extends Snapshot<Transport> {
}
function createEntityStore<T extends { id: string }>() {
const store = ref(new Map<string, T>()) as unknown as Ref<Map<string, T>>
const onAddEvent = createEventHook<T>()
const onRemoveEvent = createEventHook<string>()
const values = computed(() => Array.from(store.value.values()))
async function add(entity: T) {
store.value.set(entity.id, entity)
// eslint-disable-next-line ts/ban-ts-comment
// @ts-expect-error
await onAddEvent.trigger(entity)
}
async function remove(id: string) {
store.value.delete(id)
await onRemoveEvent.trigger(id)
}
function get(id: string) {
return store.value.get(id)
}
function clear() {
store.value.clear()
}
return {
store,
values,
onAdd: onAddEvent.on,
onRemove: onRemoveEvent.on,
add,
remove,
get,
clear,
}
}
export const useMediasoup = createGlobalState(() => {
const device = shallowRef<Device>()
const sendTransport = shallowRef<Transport>()
const recvTransport = shallowRef<Transport>()
const producers = createEntityStore<ProducerSnapshot>()
producers.onAdd((producer) => {
producer.ref.observer.on('pause', () => {
producers.store.value.set(producer.id, { ...producer, paused: true })
})
producer.ref.observer.on('resume', () => {
producers.store.value.set(producer.id, { ...producer, paused: false })
})
producer.ref.observer.on('close', () => producers.remove(producer.id))
})
const consumers = createEntityStore<ConsumerSnapshot>()
consumers.onAdd((consumer) => {
consumer.ref.on('trackended', () => consumer.ref.close())
consumer.ref.observer.on('pause', () => {
consumers.store.value.set(consumer.id, { ...consumer, paused: true })
})
consumer.ref.observer.on('resume', () => {
consumers.store.value.set(consumer.id, { ...consumer, paused: false })
})
consumer.ref.observer.on('close', () => consumers.remove(consumer.id))
})
const transports = createEntityStore<TransportSnapshot>()
transports.onAdd((transport) => {
transport.ref.observer.on('close', () => transports.remove(transport.id))
})
function clearAll() {
device.value = undefined
sendTransport.value = undefined
recvTransport.value = undefined
producers.clear()
consumers.clear()
transports.clear()
}
return {
device,
sendTransport,
recvTransport,
producers,
consumers,
transports,
clearAll,
}
})