120 lines
3.1 KiB
TypeScript
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,
|
|
}
|
|
})
|