работаем бля работаем
This commit is contained in:
119
server/plugins/socket/webrtc/Channel.ts
Normal file
119
server/plugins/socket/webrtc/Channel.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import type { types } from 'mediasoup'
|
||||
import type { ActiveSpeakerObserverDominantSpeaker } from 'mediasoup/types'
|
||||
import type { Client } from './Client.ts'
|
||||
import { EventEmitter } from 'node:events'
|
||||
|
||||
interface ChannelEvents {
|
||||
'speaking-peers': [{
|
||||
socketId: string
|
||||
volume: number
|
||||
}[]]
|
||||
'silence': []
|
||||
'active-speaker': [socketId: string]
|
||||
'empty': []
|
||||
}
|
||||
|
||||
export class Channel extends EventEmitter<ChannelEvents> {
|
||||
readonly id: string
|
||||
readonly persistent: boolean
|
||||
readonly #audioLevelObserver: types.AudioLevelObserver
|
||||
readonly #activeSpeakerObserver: types.ActiveSpeakerObserver
|
||||
readonly #clients = new Map<string, Client>()
|
||||
|
||||
private constructor(
|
||||
id: string,
|
||||
persistent: boolean,
|
||||
audioLevelObserver: types.AudioLevelObserver,
|
||||
activeSpeakerObserver: types.ActiveSpeakerObserver,
|
||||
) {
|
||||
super()
|
||||
|
||||
this.id = id
|
||||
this.persistent = persistent
|
||||
this.#audioLevelObserver = audioLevelObserver
|
||||
this.#activeSpeakerObserver = activeSpeakerObserver
|
||||
|
||||
this.#audioLevelObserver.on('volumes', (volumes: types.AudioLevelObserverVolume[]) => {
|
||||
this.emit('speaking-peers', volumes.map(({ producer, volume }) => {
|
||||
const { socketId } = producer.appData as { socketId: string }
|
||||
return { socketId, volume }
|
||||
}))
|
||||
})
|
||||
|
||||
this.#audioLevelObserver.on('silence', () => {
|
||||
this.emit('silence')
|
||||
})
|
||||
|
||||
this.#activeSpeakerObserver.on('dominantspeaker', ({ producer }: ActiveSpeakerObserverDominantSpeaker) => {
|
||||
const { socketId } = producer.appData as { socketId: string }
|
||||
this.emit('active-speaker', socketId)
|
||||
})
|
||||
}
|
||||
|
||||
static async create(id: string, persistent: boolean, router: types.Router): Promise<Channel> {
|
||||
const audioLevelObserver = await router.createAudioLevelObserver({
|
||||
maxEntries: 10,
|
||||
threshold: -80,
|
||||
interval: 800,
|
||||
})
|
||||
|
||||
const activeSpeakerObserver = await router.createActiveSpeakerObserver()
|
||||
|
||||
return new Channel(id, persistent, audioLevelObserver, activeSpeakerObserver)
|
||||
}
|
||||
|
||||
get clients(): Client[] {
|
||||
return Array.from(this.#clients.values())
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this.#clients.size
|
||||
}
|
||||
|
||||
getClient(socketId: string): Client | undefined {
|
||||
return this.#clients.get(socketId)
|
||||
}
|
||||
|
||||
addClient(client: Client): void {
|
||||
client.channelId = this.id
|
||||
this.#clients.set(client.socketId, client)
|
||||
}
|
||||
|
||||
kickClient(client: Client): void {
|
||||
this.#clients.delete(client.socketId)
|
||||
|
||||
if (this.#clients.size === 0)
|
||||
this.emit('empty')
|
||||
}
|
||||
|
||||
async addAudioProducer(producer: types.Producer): Promise<void> {
|
||||
if (producer.kind !== 'audio')
|
||||
return
|
||||
|
||||
await this.#audioLevelObserver.addProducer({ producerId: producer.id })
|
||||
await this.#activeSpeakerObserver.addProducer({ producerId: producer.id })
|
||||
}
|
||||
|
||||
async wireClient(client: Client): Promise<void> {
|
||||
for (const otherClient of this.#clients.values()) {
|
||||
if (otherClient.socketId === client.socketId)
|
||||
continue
|
||||
|
||||
for (const producer of otherClient.producers.values()) {
|
||||
await client.createConsumerFor(producer, otherClient.socketId)
|
||||
}
|
||||
|
||||
for (const producer of client.producers.values()) {
|
||||
await otherClient.createConsumerFor(producer, client.socketId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unwireClient(client: Client): void {
|
||||
for (const otherClient of this.#clients.values()) {
|
||||
for (const producerId of client.producers.keys()) {
|
||||
otherClient.removeConsumersOf(producerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user