vani-meeting-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,468 @@
1
+ import { Router } from "mediasoup/node/lib/Router";
2
+ import { BaseSFUWebsocket } from "../base/BaseSFUWebsocket";
3
+ import { Participant } from "../models/Participant";
4
+ import { SFUMessageType } from "../websocket/EachSocketConnectionHandler";
5
+ import { SFUEachRoomHandlerInterface, SFUEachRoomProducer, SFUMessageBody } from "./SFUEachRoomHandler";
6
+ import { WebRtcTransport } from "mediasoup/node/lib/WebRtcTransport";
7
+ import { Transport } from "mediasoup/node/lib/Transport";
8
+ import { Producer } from "mediasoup/node/lib/Producer";
9
+ import { Consumer } from "mediasoup/node/lib/Consumer";
10
+ import webrtcTransportConfiguration from "../utility/Constant";
11
+
12
+ export class SFUEachRoomUserHandler extends BaseSFUWebsocket {
13
+
14
+ private isUserPresentInRoom = true
15
+ public selfParticipant: Participant
16
+ public recvRouter?: Router;
17
+ public sendRouter?: Router;
18
+ private webrtcSendTransport?: WebRtcTransport
19
+ private webrtcRecieveTransport?: WebRtcTransport
20
+ private roomHandlerDataSource?: SFUEachRoomHandlerInterface
21
+ public producers: Producer[] = []
22
+ public consumers: Consumer[] = []
23
+
24
+ constructor(participant: Participant, sendRouter: Router, recvRouters: Router, roomHandlerDataSource: SFUEachRoomHandlerInterface) {
25
+ super()
26
+ this.selfParticipant = participant;
27
+ this.sendRouter = sendRouter
28
+ this.recvRouter = recvRouters
29
+ this.roomHandlerDataSource = roomHandlerDataSource
30
+ this.checkAllProducerAndConsuer = this.checkAllProducerAndConsuer.bind(this)
31
+ this.onConsumeProductId = this.onConsumeProductId.bind(this)
32
+ this.onReadyToConsume = this.onReadyToConsume.bind(this)
33
+ this.resumeConsumer = this.resumeConsumer.bind(this)
34
+ this.pauseConsumer = this.pauseConsumer.bind(this)
35
+ this.updateSpatialConsumer = this.updateSpatialConsumer.bind(this)
36
+ this.onTransportProduceSyncRequest = this.onTransportProduceSyncRequest.bind(this)
37
+ this.onResumeProducer = this.onResumeProducer.bind(this)
38
+ this.onPauseProducer = this.onPauseProducer.bind(this)
39
+ this.onNewProducer = this.onNewProducer.bind(this)
40
+ this.onGetAllProducers = this.onGetAllProducers.bind(this)
41
+ this.onProducerClosed = this.onProducerClosed.bind(this)
42
+ this.createWebrtcSendTransport = this.createWebrtcSendTransport.bind(this)
43
+ this.createWebrtcRecieveTransport = this.createWebrtcRecieveTransport.bind(this)
44
+ this.connectTransport = this.connectTransport.bind(this)
45
+ this.onRestartIceCandidate = this.onRestartIceCandidate.bind(this)
46
+ this.checkAllProducerAndConsuer = this.checkAllProducerAndConsuer.bind(this)
47
+ this.cleanUp = this.cleanUp.bind(this)
48
+
49
+ setTimeout(this.checkAllProducerAndConsuer, 5000)
50
+ }
51
+
52
+ public onNewMessage(payload: SFUMessageBody) {
53
+ if (payload.type === SFUMessageType.OnCreateTransports) {
54
+ this.createWebrtcSendTransport(this.selfParticipant)
55
+ this.createWebrtcRecieveTransport(this.selfParticipant)
56
+ }
57
+ else if (payload.type === SFUMessageType.OnTransportConnect) {
58
+ this.connectTransport(payload)
59
+ }
60
+ else if (payload.type === SFUMessageType.OnTransportProduceSyncRequest) {
61
+ this.onTransportProduceSyncRequest(payload)
62
+ }
63
+ else if (payload.type === SFUMessageType.OnReadyToConsume) {
64
+ this.onReadyToConsume(payload)
65
+ }
66
+ else if (payload.type === SFUMessageType.ConsumeProductId) {
67
+ this.onConsumeProductId(payload)
68
+ }
69
+ else if (payload.type === SFUMessageType.ResumeConsumer) {
70
+ this.resumeConsumer(payload)
71
+ }
72
+ else if (payload.type === SFUMessageType.PauseConsumer) {
73
+ this.pauseConsumer(payload)
74
+ }
75
+ else if (payload.type === SFUMessageType.UpdateSpatialConsumer) {
76
+ this.updateSpatialConsumer(payload)
77
+ }
78
+ else if (payload.type === SFUMessageType.OnProducerClosed) {
79
+ this.onProducerClosed(payload)
80
+ }
81
+ else if (payload.type === SFUMessageType.OnResumeProducer) {
82
+ this.onResumeProducer(payload)
83
+ }
84
+ else if (payload.type === SFUMessageType.OnPauseProducer) {
85
+ this.onPauseProducer(payload)
86
+ }
87
+ else if (payload.type === SFUMessageType.OnRestartIceCandidate) {
88
+ this.onRestartIceCandidate(payload)
89
+ }
90
+ else if (payload.type === SFUMessageType.GetAllProducers) {
91
+ this.onGetAllProducers(payload)
92
+ }
93
+ else if (payload.type === SFUMessageType.OnStopProducer) {
94
+ this.onProducerClosed(payload)
95
+ }
96
+
97
+ }
98
+
99
+
100
+
101
+ private async onConsumeProductId(payload: SFUMessageBody) {
102
+ try {
103
+ if (this.roomHandlerDataSource) {
104
+
105
+ const producer = this.roomHandlerDataSource.getProducerById(payload.message.producerId)
106
+ if (producer && producer.producer.closed === false) {
107
+
108
+ const consumer = await this.webrtcRecieveTransport?.consume(payload.message)
109
+ if (consumer) {
110
+ consumer.on("producerclose", () => {
111
+ console.log("producerclose");
112
+ consumer.close()
113
+ this.consumers = this.consumers.filter((eachConsumer) => eachConsumer.id !== consumer.id)
114
+ const response = { producerId: consumer.producerId }
115
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnTrackEnded, response)));
116
+
117
+ })
118
+ consumer.on("producerpause", () => {
119
+ console.log("producerpause");
120
+
121
+ if (consumer.closed === false) {
122
+ consumer.pause()
123
+ }
124
+ })
125
+ consumer.on("producerresume", () => {
126
+ console.log("producerresume");
127
+
128
+ if (consumer.closed === false) {
129
+ consumer.resume()// To be Done
130
+ }
131
+ })
132
+ consumer.on("@close", () => {
133
+ console.log("On closed")
134
+ this.consumers = this.consumers.filter((eachConsumer) => eachConsumer.id !== consumer.id)
135
+ })
136
+ this.consumers.push(consumer)
137
+ const consumeData = { consumer: { id: consumer?.id, producerId: consumer?.producerId, kind: consumer?.kind, rtpParameters: consumer?.rtpParameters, appData: consumer?.appData } }
138
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnServerConsumer, consumeData)));
139
+ }
140
+ else {
141
+ console.error("Not able to consume")
142
+ }
143
+ }
144
+ else {
145
+ console.error(" onConsumeProductId : Producer not found ", this.selfParticipant.userData.name, payload)
146
+ }
147
+ }
148
+
149
+ }
150
+ catch (err) {
151
+ console.error(" Product Consume Error ", payload)
152
+ console.error(err)
153
+ }
154
+
155
+
156
+ }
157
+
158
+ private onReadyToConsume(payload: SFUMessageBody) {
159
+ if (this.roomHandlerDataSource) {
160
+ this.roomHandlerDataSource.getAllProducerForRoom().forEach((eachRoomProducer: SFUEachRoomProducer) => {
161
+ if (eachRoomProducer.participant.userId && this.selfParticipant.userId && eachRoomProducer.participant.userId !== this.selfParticipant.userId && eachRoomProducer.producer) {
162
+ const producerData = { producer: { id: eachRoomProducer.producer.id, rtpParameters: eachRoomProducer.producer.rtpParameters, appData: eachRoomProducer.producer.appData } }
163
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnNewProducer, producerData)));
164
+ console.log("On New Producer")
165
+ }
166
+ })
167
+ }
168
+ }
169
+
170
+ private resumeConsumer(payload: SFUMessageBody) {
171
+ const consumerId = payload.message.id;
172
+ if (consumerId) {
173
+ const consumer = this.consumers.find((consumer) => consumer.id === consumerId)
174
+ if (consumer && consumer.closed === false && consumer?.producerPaused === false) {
175
+ consumer.resume()
176
+ console.log("resumeConsumer", this.selfParticipant.userData.name)
177
+
178
+ }
179
+ else if (!consumer) {
180
+ console.error(" resumeConsumer : Consumer not found ")
181
+
182
+ }
183
+ }
184
+ }
185
+ private pauseConsumer(payload: SFUMessageBody) {
186
+ const consumerId = payload.message.id;
187
+ if (consumerId) {
188
+ const consumer = this.consumers.find((consumer) => consumer.id === consumerId)
189
+ if (consumer && consumer.closed === false) {
190
+ consumer.pause()
191
+ console.log("pauseConsumer", this.selfParticipant.userData.name)
192
+
193
+ }
194
+ else if (!consumer) {
195
+ console.error(" pauseConsumer : Consumer not found ")
196
+ }
197
+ }
198
+ }
199
+ private updateSpatialConsumer(payload: SFUMessageBody) {
200
+ const consumerId = payload.message.id;
201
+ const spatialLayer = payload.message.spatialLayer
202
+ if (consumerId && spatialLayer !== undefined) {
203
+ const consumer = this.consumers.find((consumer) => consumer.id === consumerId)
204
+ if (consumer && consumer.closed === false) {
205
+ console.log("updateSpatialConsumer consumer", consumer.id)
206
+
207
+ try {
208
+ consumer.setPreferredLayers({ spatialLayer: spatialLayer })
209
+ console.log("consumer.setPreferredLayers", spatialLayer)
210
+ }
211
+ catch (err) {
212
+ console.error(err)
213
+ }
214
+ }
215
+ else if (!consumer) {
216
+ console.error(" updateSpatialConsumer : Consumer not found ")
217
+ }
218
+ }
219
+ }
220
+
221
+
222
+
223
+ private async onTransportProduceSyncRequest(payload: SFUMessageBody) {
224
+ if (this.roomHandlerDataSource) {
225
+
226
+ const producer = await this.webrtcSendTransport?.produce(payload.message)
227
+
228
+ if (producer) {
229
+ await this.onNewProducer(producer)
230
+ if (producer.kind === 'audio') {
231
+ this.roomHandlerDataSource.addAudioObserverForProducer(producer)
232
+ }
233
+
234
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnProduceSyncDone, { transportId: this.webrtcSendTransport?.id, producerId: producer.id, appData: producer.appData })));
235
+ }
236
+ else {
237
+ console.error(" Error in creating producer ", payload)
238
+ }
239
+ }
240
+
241
+
242
+ }
243
+
244
+ private async onResumeProducer(payload: SFUMessageBody) {
245
+ const producerId = payload.message.producerId
246
+ const producer = this.producers.find((eachProducer) => eachProducer.id === producerId)
247
+ if (producer && producer.closed === false) {
248
+ producer.resume()
249
+ }
250
+ }
251
+ private async onPauseProducer(payload: SFUMessageBody) {
252
+ const producerId = payload.message.producerId
253
+ const producer = this.producers.find((eachProducer) => eachProducer.id === producerId)
254
+ if (producer && producer.closed === false) {
255
+ producer.pause()
256
+ }
257
+ }
258
+ private async onNewProducer(producer: Producer) {
259
+ if (this.roomHandlerDataSource) {
260
+
261
+ if (producer.closed === false) {
262
+ await this.roomHandlerDataSource.pipeToRoute(producer)
263
+ this.producers.push(producer)
264
+ this.redisBroadcastMessageToTopic(this.selfParticipant.roomId!, this.preapreClientMessageBody(false, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnNewProducer, { producer: { id: producer.id, appData: producer.appData } })));
265
+ }
266
+ }
267
+ }
268
+
269
+ private async onGetAllProducers(payload: SFUMessageBody) {
270
+ const producers: Producer[] = []
271
+ if (this.roomHandlerDataSource) {
272
+
273
+ this.roomHandlerDataSource.getAllProducerForRoom().forEach((eachRoomProducer: SFUEachRoomProducer) => {
274
+ if (eachRoomProducer.participant.userId && this.selfParticipant.userId && eachRoomProducer.participant.userId !== this.selfParticipant.userId && eachRoomProducer.producer) {
275
+ producers.push(eachRoomProducer.producer)
276
+ }
277
+ })
278
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnAllProducers, { producers: producers })));
279
+ }
280
+
281
+ }
282
+ private async onProducerClosed(payload: SFUMessageBody) {
283
+ const producerId = payload.message.producerId
284
+ if (producerId) {
285
+ const producerToBeClosed = this.producers.find((eachProducer) => eachProducer.id === producerId)
286
+ if (producerToBeClosed) {
287
+ console.log("onProducerClosed", payload.message)
288
+ producerToBeClosed.close()
289
+ const response = { producerId: producerId }
290
+ this.redisBroadcastMessageToTopic(this.selfParticipant.roomId!, this.preapreClientMessageBody(false, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnTrackEnded, response)));
291
+ this.producers = this.producers.filter((eachProducer) => eachProducer.id !== producerId)
292
+ }
293
+ }
294
+
295
+ }
296
+
297
+ private async createWebrtcSendTransport(participant: Participant) {
298
+ if (!this.sendRouter) {
299
+ console.error("createWebrtcRecieveTransport no send router found ", participant.roomId!)
300
+ return
301
+ }
302
+
303
+
304
+ if (!this.webrtcSendTransport || this.webrtcSendTransport.closed) {
305
+ this.webrtcSendTransport = await this.sendRouter?.createWebRtcTransport(await webrtcTransportConfiguration())
306
+ if (this.webrtcSendTransport) {
307
+ this.webrtcSendTransport!.appData.type = 'send'
308
+ this.webrtcSendTransport!.appData.userId = participant.userId
309
+ this.webrtcSendTransport!.appData.participant = participant
310
+ this.webrtcSendTransport!.on("@newproducer", (produce) => {
311
+ })
312
+ }
313
+ else {
314
+ console.error("createWebrtcSendTransport Transport not created ", participant.roomId!)
315
+
316
+ }
317
+ }
318
+ if (this.webrtcSendTransport) {
319
+ const transportOptionForClient = {
320
+ iceRole: this.webrtcSendTransport.iceRole,
321
+ iceParameters: this.webrtcSendTransport.iceParameters,
322
+ iceCandidates: this.webrtcSendTransport.iceCandidates,
323
+ iceState: this.webrtcSendTransport.iceState,
324
+ iceSelectedTuple: this.webrtcSendTransport.iceSelectedTuple,
325
+ dtlsParameters: this.webrtcSendTransport.dtlsParameters,
326
+ dtlsState: this.webrtcSendTransport.dtlsState,
327
+ dtlsRemoteCert: this.webrtcSendTransport.dtlsRemoteCert,
328
+ sctpParameters: this.webrtcSendTransport.sctpParameters,
329
+ sctpState: this.webrtcSendTransport.sctpState,
330
+ id: this.webrtcSendTransport.id,
331
+ appData: this.webrtcSendTransport.appData
332
+ }
333
+ this.redisBroadcastMessageToTopic(participant.userId!, this.preapreClientMessageBody(true, participant, this.preapreWebSocketMessageBody(SFUMessageType.OnSendTransport, { transport: transportOptionForClient })));
334
+ }
335
+ }
336
+ private async createWebrtcRecieveTransport(participant: Participant) {
337
+ if (!this.recvRouter) {
338
+ console.error("createWebrtcRecieveTransport no recieve router found ", participant.roomId!)
339
+ return
340
+ }
341
+
342
+ if (!this.webrtcRecieveTransport || this.webrtcRecieveTransport.closed) {
343
+ this.webrtcRecieveTransport = await this.sendRouter?.createWebRtcTransport(await webrtcTransportConfiguration())
344
+ if (this.webrtcRecieveTransport) {
345
+ this.webrtcRecieveTransport!.appData.type = 'consumer'
346
+ this.webrtcRecieveTransport!.appData.userId = participant.userId
347
+ this.webrtcRecieveTransport!.appData.participant = participant
348
+ }
349
+ else {
350
+ console.error("webrtcRecieveTransport Transport not created ", participant.roomId!)
351
+
352
+ }
353
+ }
354
+ if (this.webrtcRecieveTransport) {
355
+ const transportOptionForClient = {
356
+ iceRole: this.webrtcRecieveTransport.iceRole,
357
+ iceParameters: this.webrtcRecieveTransport.iceParameters,
358
+ iceCandidates: this.webrtcRecieveTransport.iceCandidates,
359
+ iceState: this.webrtcRecieveTransport.iceState,
360
+ iceSelectedTuple: this.webrtcRecieveTransport.iceSelectedTuple,
361
+ dtlsParameters: this.webrtcRecieveTransport.dtlsParameters,
362
+ dtlsState: this.webrtcRecieveTransport.dtlsState,
363
+ dtlsRemoteCert: this.webrtcRecieveTransport.dtlsRemoteCert,
364
+ sctpParameters: this.webrtcRecieveTransport.sctpParameters,
365
+ sctpState: this.webrtcRecieveTransport.sctpState,
366
+ id: this.webrtcRecieveTransport.id,
367
+ appData: this.webrtcRecieveTransport.appData
368
+ }
369
+ this.redisBroadcastMessageToTopic(participant.userId!, this.preapreClientMessageBody(true, participant, this.preapreWebSocketMessageBody(SFUMessageType.OnConsumeTransport, { transport: transportOptionForClient })));
370
+ }
371
+ }
372
+
373
+
374
+ private async connectTransport(payload: SFUMessageBody) {
375
+ let transport;
376
+ if (payload.message.type && payload.message.type === 'send') {
377
+ transport = this.webrtcSendTransport
378
+ }
379
+ if (payload.message.type && payload.message.type === 'consumer') {
380
+ transport = this.webrtcRecieveTransport
381
+ }
382
+ const dtlsParameters = payload.message.dtlsParameters
383
+ if (transport) {
384
+ await transport.connect({ dtlsParameters })
385
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnTransportConnectDone, { transportId: transport.id })));
386
+ }
387
+ else {
388
+ console.error("connectTransport no transport found ", payload)
389
+ }
390
+ }
391
+
392
+
393
+
394
+ private async onRestartIceCandidate(payload: SFUMessageBody) {
395
+ const transportId = payload.message.transportId
396
+ if (transportId) {
397
+ let transport: WebRtcTransport | undefined = undefined
398
+ if (this.webrtcRecieveTransport?.id === transportId) {
399
+ transport = this.webrtcRecieveTransport
400
+ }
401
+ else if (this.webrtcSendTransport?.id === transportId) {
402
+ transport = this.webrtcSendTransport
403
+ }
404
+
405
+ if (transport) {
406
+ const iceParameters = await transport.restartIce()
407
+ const response = { iceParameters: iceParameters, transportId: transportId }
408
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnRestartIceCandidateResponse, response)));
409
+
410
+ }
411
+ else {
412
+ const response = { transportId: transportId }
413
+ this.redisBroadcastMessageToTopic(this.selfParticipant.userId!, this.preapreClientMessageBody(true, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnTransportNotFound, response)));
414
+
415
+ }
416
+ }
417
+ }
418
+
419
+ private async checkAllProducerAndConsuer() {
420
+ if (this.isUserPresentInRoom) {
421
+ try {
422
+ // console.log("checkAllProducerAndConsuer")
423
+ this.producers.forEach((eachProducer) => {
424
+ if (eachProducer && eachProducer.closed === true) {
425
+ const response = { producerId: eachProducer.id }
426
+ this.redisBroadcastMessageToTopic(this.selfParticipant.roomId!, this.preapreClientMessageBody(false, this.selfParticipant, this.preapreWebSocketMessageBody(SFUMessageType.OnTrackEnded, response)));
427
+ }
428
+ })
429
+
430
+ this.producers = this.producers.filter((eachProducer) =>
431
+ eachProducer.closed === false
432
+ )
433
+ }
434
+ catch (err) {
435
+ console.error(err)
436
+ }
437
+ if (this.isUserPresentInRoom) {
438
+ setTimeout(this.checkAllProducerAndConsuer, 8000)
439
+
440
+
441
+ }
442
+ }
443
+
444
+ }
445
+
446
+ public cleanUp() {
447
+ this.isUserPresentInRoom = false
448
+ this.roomHandlerDataSource = undefined
449
+ this.producers.forEach(producer => {
450
+ producer.close()
451
+ });
452
+ this.consumers.forEach(consumer => {
453
+ consumer.close()
454
+ });
455
+ if (this.webrtcSendTransport) {
456
+ this.webrtcSendTransport.close()
457
+ this.webrtcSendTransport = undefined
458
+ }
459
+ if (this.webrtcRecieveTransport) {
460
+ this.webrtcRecieveTransport.close()
461
+ this.webrtcRecieveTransport = undefined
462
+ }
463
+ this.recvRouter = this.sendRouter = undefined
464
+ this.producers = []
465
+ this.consumers = []
466
+ }
467
+
468
+ }
@@ -0,0 +1,67 @@
1
+
2
+ import os from 'os';
3
+ import { Worker } from 'mediasoup/node/lib/Worker';
4
+ import { SFUEachRoomHandler } from './SFUEachRoomHandler';
5
+ import { Participant } from '../models/Participant';
6
+ import { ServerHandler } from '../ServerHandler';
7
+ const mediasoup = require("mediasoup");
8
+
9
+ export class SFUHandler {
10
+
11
+ static instance = new SFUHandler()
12
+ private workers: Worker[] = []
13
+ private sfuRooms = new Map<string, SFUEachRoomHandler>()
14
+
15
+ static getInstance() {
16
+ return SFUHandler.instance;
17
+ }
18
+
19
+ constructor() {
20
+ this.init = this.init.bind(this)
21
+ this.createWorkers = this.createWorkers.bind(this)
22
+
23
+ }
24
+
25
+
26
+
27
+ public async init() {
28
+
29
+ await this.createWorkers()
30
+ }
31
+
32
+ public async checkAndSetupRoom(roomId: string) {
33
+ if (this.sfuRooms.has(roomId) === false) {
34
+ console.log("On New Room")
35
+ const sfuEachRoomHandler = new SFUEachRoomHandler(roomId, this.workers, (this.sfuRooms.size % this.workers.length))
36
+ this.sfuRooms.set(roomId, sfuEachRoomHandler)
37
+ }
38
+ }
39
+
40
+ public checkIfCanCloseRoom(roomId: string) {
41
+ const room = this.getRoomSFUHandler(roomId)
42
+ if (room && room.roomPaticipants.size === 0) {
43
+ room.cleanUp()
44
+ this.sfuRooms.delete(roomId)
45
+ }
46
+ }
47
+
48
+ public getRoomSFUHandler(roomId: string): SFUEachRoomHandler | undefined {
49
+ if (this.sfuRooms.has(roomId)) {
50
+ return this.sfuRooms.get(roomId)
51
+ }
52
+ else {
53
+ console.error("No Room Found During SFU Message", roomId)
54
+ }
55
+ }
56
+
57
+ private async createWorkers() {
58
+ while (this.workers.length < os.cpus().length) {
59
+ mediasoup.logLevel = "info"
60
+ const worker: Worker = await mediasoup.createWorker({ rtcMinPort: ServerHandler.getInstance().serverStartRequest.rtcMinPort, rtcMaxPort: ServerHandler.getInstance().serverStartRequest.rtcMaxPort })
61
+ worker.updateSettings({ logLevel: "debug" })
62
+ this.workers.push(worker)
63
+ }
64
+
65
+ }
66
+
67
+ }
@@ -0,0 +1,63 @@
1
+ import { RtpCodecCapability } from "mediasoup/node/lib/RtpParameters";
2
+ import { WebRtcTransportOptions } from "mediasoup/node/lib/WebRtcTransport";
3
+ import { ServerHandler } from "../ServerHandler";
4
+ const publicIp = require('public-ip');
5
+ let publicIpAddress : string | undefined;
6
+ (async () => {
7
+ publicIpAddress = await publicIp.v4();
8
+ console.log(publicIpAddress)
9
+ })();
10
+ export const mediaCodecs: RtpCodecCapability[] = [
11
+ {
12
+ kind: 'audio',
13
+ mimeType: 'audio/opus',
14
+ clockRate: 48000,
15
+ channels: 2
16
+ },
17
+ {
18
+ kind: 'video',
19
+ mimeType: 'video/VP8',
20
+ clockRate: 90000,
21
+ parameters: {
22
+ 'x-google-start-bitrate': 1000
23
+ }
24
+ },
25
+ {
26
+ kind: 'video',
27
+ mimeType: 'video/VP9',
28
+ clockRate: 90000,
29
+ parameters: {
30
+ 'profile-id': 2,
31
+ 'x-google-start-bitrate': 1000
32
+ }
33
+ },
34
+ {
35
+ kind: 'video',
36
+ mimeType: 'video/h264',
37
+ clockRate: 90000,
38
+ parameters: {
39
+ 'packetization-mode': 1,
40
+ 'profile-level-id': '42001f',
41
+ 'level-asymmetry-allowed': 1,
42
+ 'x-google-start-bitrate': 1000
43
+ }
44
+ }
45
+ ];
46
+
47
+
48
+ export default async function webrtcTransportConfiguration() {
49
+ if(!publicIpAddress){
50
+ publicIpAddress = await publicIp.v4();
51
+ }
52
+ return {
53
+
54
+ listenIps: [{ ip: '0.0.0.0', announcedIp: publicIpAddress }],
55
+ enableUdp: true,
56
+ enableTcp: true,
57
+ preferUdp: !ServerHandler.getInstance().serverStartRequest.isTCPConnection ,
58
+ preferTcp: ServerHandler.getInstance().serverStartRequest.isTCPConnection,
59
+ maxSctpMessageSize: 262144 * 10,
60
+ sctpSendBufferSize: 262144 * 10,
61
+ enableSctp: true,
62
+ }
63
+ }
@@ -0,0 +1,10 @@
1
+ import { VaniEventListener } from "./VaniEventListener";
2
+
3
+ export class EventEmitterHandler {
4
+
5
+ static instance = new EventEmitterHandler()
6
+ public vaniEventEmitter : VaniEventListener = new VaniEventListener()
7
+ static getInstance(): EventEmitterHandler {
8
+ return EventEmitterHandler.instance;
9
+ }
10
+ }
@@ -0,0 +1,7 @@
1
+ import * as events from "events";
2
+
3
+ export class VaniEventListener extends events.EventEmitter {
4
+
5
+ }
6
+
7
+