Skip to content

Commit fa8e660

Browse files
authored
Merge pull request #3 from waterbustech/feat/recorder
Feat/recorder
2 parents 3a05885 + 1c17235 commit fa8e660

24 files changed

+1149
-278
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ lerna-debug.log*
3434
!.vscode/launch.json
3535
!.vscode/extensions.json
3636

37-
.env
37+
.env
38+
rec
39+
credentials.json

ecosystem.config.js

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = {
1414
error_file: 'logs/error.log',
1515
out_file: 'logs/out.log',
1616
log_date_format: 'YYYY-MM-DD HH:mm:ss',
17+
kill_timeout: 30000,
1718
},
1819
{
1920
name: 'waterbus.sfu.ws.02',
@@ -31,6 +32,7 @@ module.exports = {
3132
error_file: 'logs/error.log',
3233
out_file: 'logs/out.log',
3334
log_date_format: 'YYYY-MM-DD HH:mm:ss',
35+
kill_timeout: 30000,
3436
},
3537
],
3638
};

env-example

-6
This file was deleted.

example.env

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# App
2+
PORT=5985
3+
HOSTNAME=waterbus01
4+
5+
# GRPC
6+
WEBSOCKET_GRPC_ADDRESS=0.0.0.0:50054
7+
AUTH_GRPC_ADDRESS=0.0.0.0:50055
8+
MEETING_GRPC_ADDRESS=0.0.0.0:50056
9+
10+
# Microservices
11+
IS_MICROSERVICES=true
12+
# IS_USE_PM2=true
13+
REDIS_URL=redis://localhost:6379
14+
15+
# Ice Servers
16+
TURN_USERNAME=waterbus
17+
TURN_CREDENTIAL=lambiengcode

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
"pm2:start": "pm2 start ecosystem.config.js"
2323
},
2424
"dependencies": {
25+
"@discordjs/opus": "^0.8.0",
26+
"@google-cloud/speech": "^6.5.0",
2527
"@grpc/grpc-js": "^1.10.5",
2628
"@nestjs/common": "^9.0.0",
2729
"@nestjs/config": "^3.2.1",
@@ -33,8 +35,11 @@
3335
"@nestjs/websockets": "^10.3.7",
3436
"@socket.io/redis-adapter": "^8.3.0",
3537
"@types/mime": "3.0.4",
38+
"audio-decode": "^2.2.0",
39+
"blob": "^0.1.0",
3640
"dotenv": "^16.4.5",
3741
"google-protobuf": "^3.21.2",
42+
"multicast-dns": "^7.2.5",
3843
"redis": "^4.6.13",
3944
"reflect-metadata": "^0.1.13",
4045
"rxjs": "^7.8.1",

src/domain/constants/socket_events.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@ const SocketEvent = {
2222
setAudioEnabledSSC: 'SET_AUDIO_ENABLED_SSC',
2323
setScreenSharingSSC: 'SET_SCREEN_SHARING_SSC',
2424
setScreenSharingCSS: 'SET_SCREEN_SHARING_CSS',
25+
handRaisingSSC: 'HAND_RAISING_SSC',
26+
handRaisingCSS: 'HAND_RAISING_CSS',
27+
subtitleSSC: 'SUBTITLE_SSC',
28+
setSubscribeSubtitleCSS: 'SET_SUBSCRIBE_SUBTITLE_CSS',
2529

2630
// Chats
2731
sendMessageSSC: 'SEND_MESSAGE_SSC',
2832
updateMessageSSC: 'UPDATE_MESSAGE_SSC',
2933
deleteMessageSSC: 'DELETE_MESSAGE_SSC',
3034

31-
// Default
35+
// System
3236
connection: 'connection',
3337
disconnect: 'disconnect',
38+
destroy: 'destroy_',
3439
} as const;
3540

3641
export default SocketEvent;

src/infrastructure/config/socket/redis.adapter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export class RedisIoAdapter extends IoAdapter {
4242
token: accessToken,
4343
});
4444

45-
if (verifyResponse.valid) {
45+
if (verifyResponse && verifyResponse.valid) {
4646
request['userId'] = verifyResponse.userId;
4747
return allowFunction(null, true);
4848
}

src/infrastructure/gateways/gateway.module.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Module } from '@nestjs/common';
1+
import { Module, forwardRef } from '@nestjs/common';
22
import { SocketGateway } from './socket/socket.gateway';
33
import { MeetingGateway } from './meeting/meeting.gateway';
44
import { MeetingGrpcService } from 'src/infrastructure/services/meeting/meeting.service';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
3+
export class SetSubscribeSubtitleDto {
4+
@ApiProperty({ type: Boolean })
5+
enabled: boolean;
6+
}

src/infrastructure/gateways/meeting/dtos/subscribe.dto.ts

+6
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,10 @@ import { ApiProperty } from '@nestjs/swagger';
33
export class SubscribeDto {
44
@ApiProperty({ type: String })
55
targetId: string;
6+
7+
@ApiProperty({ type: String })
8+
roomId: string;
9+
10+
@ApiProperty({ type: String })
11+
participantId: string;
612
}

src/infrastructure/gateways/meeting/meeting.gateway.ts

+46-9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { MeetingGrpcService } from 'src/infrastructure/services/meeting/meeting.
2121
import RedisEvents from 'src/domain/constants/redis_events';
2222
import { MessageBroker } from 'src/infrastructure/services/message-broker/message-broker';
2323
import { EnvironmentConfigService } from 'src/infrastructure/config/environment/environments';
24+
import { SetSubscribeSubtitleDto } from './dtos/set_subscribe_subtitle.dto';
2425

2526
@WebSocketGateway()
2627
export class MeetingGateway {
@@ -36,7 +37,7 @@ export class MeetingGateway {
3637
}
3738

3839
@WebSocketServer() private server: Server;
39-
private logger: Logger = new Logger('MeetingGateway');
40+
private logger: Logger = new Logger(MeetingGateway.name);
4041

4142
@SubscribeMessage(SocketEvent.publishCSS)
4243
async handleJoinRoom(client: ISocketClient, payload: JoinRoomDto) {
@@ -102,18 +103,12 @@ export class MeetingGateway {
102103
...responsePayload,
103104
});
104105
} else {
105-
const clientInfo = this.rtcManager.getClientBySocketId({
106-
clientId: client.id,
107-
});
108-
109-
if (!clientInfo) return;
110-
111106
this.messageBroker.publishRedisChannel(
112107
participantInfo.ccu.podName,
113108
RedisEvents.SUBSCRIBE,
114109
{
115-
participantId: clientInfo.participantId,
116-
roomId: clientInfo.roomId,
110+
participantId: payload.participantId,
111+
roomId: payload.roomId,
117112
targetId: payload.targetId,
118113
clientId: client.id,
119114
},
@@ -321,6 +316,48 @@ export class MeetingGateway {
321316
});
322317
}
323318

319+
@SubscribeMessage(SocketEvent.handRaisingCSS)
320+
handleSetHandRaising(client: ISocketClient, payload: any): any {
321+
const clientInfo = this.rtcManager.getClientBySocketId({
322+
clientId: client.id,
323+
});
324+
325+
if (!clientInfo) return;
326+
327+
const roomId = clientInfo.roomId;
328+
const targetId = clientInfo.participantId;
329+
330+
if (!roomId) return;
331+
332+
client.broadcast.to(roomId).emit(SocketEvent.handRaisingSSC, {
333+
participantId: targetId,
334+
});
335+
}
336+
337+
@SubscribeMessage(SocketEvent.setSubscribeSubtitleCSS)
338+
handleSetSubscribeSubtitle(
339+
client: ISocketClient,
340+
payload: SetSubscribeSubtitleDto,
341+
): any {
342+
const clientInfo = this.rtcManager.getClientBySocketId({
343+
clientId: client.id,
344+
});
345+
346+
if (!clientInfo) return;
347+
348+
const roomId = clientInfo.roomId;
349+
350+
if (!roomId) return;
351+
352+
const subtitleChannel = SocketEvent.subtitleSSC + roomId;
353+
354+
if (payload.enabled) {
355+
client.join(subtitleChannel);
356+
} else {
357+
client.leave(subtitleChannel);
358+
}
359+
}
360+
324361
@SubscribeMessage(SocketEvent.leaveRoomCSS)
325362
async handleLeaveRoom(client: ISocketClient, payload: any) {
326363
const info = this.rtcManager.leaveRoom({ clientId: client.id });

src/infrastructure/gateways/socket/socket.gateway.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class SocketGateway
3131

3232
@WebSocketServer() public server: Server;
3333

34-
private logger: Logger = new Logger('SocketGateway');
34+
private logger: Logger = new Logger(SocketGateway.name);
3535

3636
afterInit(server: Server) {
3737
this.server = server;
@@ -40,15 +40,15 @@ export class SocketGateway
4040

4141
async handleConnection(client: ISocketClient) {
4242
try {
43-
this.logger.debug(`Client connected: ${client.id}`);
44-
4543
const userId = client.request['userId'];
4644

4745
this.authService.createCCU({
4846
socketId: client.id,
4947
podName: this.environment.getPodName(),
5048
userId,
5149
});
50+
51+
client.join(SocketEvent.destroy + this.environment.getPodName());
5252
} catch (error) {
5353
this.logger.error(error?.message, error?.stack);
5454
return client.disconnect(true);
@@ -86,6 +86,8 @@ export class SocketGateway
8686
try {
8787
this.logger.debug(`Pod is shutting down...`);
8888

89+
this.server.emit(SocketEvent.destroy + this.environment.getPodName());
90+
8991
// Delete CCU & participants in this pod
9092
this.authService.shutDownPod({
9193
podName: this.environment.getPodName(),

src/infrastructure/helpers/logger.ts

+32-32
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
1-
import * as winston from 'winston';
1+
// import * as winston from 'winston';
22

3-
const customFormat = winston.format.printf(({ timestamp, level, message }) => {
4-
let icon = '';
5-
switch (level) {
6-
case 'info':
7-
icon = '🦋';
8-
break;
9-
case 'warn':
10-
icon = '⚠️';
11-
break;
12-
case 'error':
13-
icon = '🐞';
14-
break;
15-
default:
16-
icon = '';
17-
break;
18-
}
19-
return `${icon} [${timestamp}][${level}]: ${message}`;
20-
});
3+
// const customFormat = winston.format.printf(({ timestamp, level, message }) => {
4+
// let icon = '';
5+
// switch (level) {
6+
// case 'info':
7+
// icon = '🦋';
8+
// break;
9+
// case 'warn':
10+
// icon = '⚠️';
11+
// break;
12+
// case 'error':
13+
// icon = '🐞';
14+
// break;
15+
// default:
16+
// icon = '';
17+
// break;
18+
// }
19+
// return `${icon} [${timestamp}][${level}]: ${message}`;
20+
// });
2121

22-
const logger = winston.createLogger({
23-
level: 'info',
24-
format: winston.format.combine(
25-
winston.format.colorize(),
26-
winston.format.timestamp(),
27-
customFormat,
28-
),
29-
transports: [
30-
new winston.transports.File({ filename: 'app.log', level: 'info' }),
31-
new winston.transports.Console(),
32-
],
33-
});
22+
// const logger = winston.createLogger({
23+
// level: 'info',
24+
// format: winston.format.combine(
25+
// winston.format.colorize(),
26+
// winston.format.timestamp(),
27+
// customFormat,
28+
// ),
29+
// transports: [
30+
// new winston.transports.File({ filename: 'app.log', level: 'info' }),
31+
// new winston.transports.Console(),
32+
// ],
33+
// });
3434

35-
export default logger;
35+
// export default logger;

src/infrastructure/services/auth/auth.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class AuthGrpcService implements OnModuleInit {
2727
private $reconnect: Subscription;
2828

2929
constructor(private readonly authClientProxy: ClientGrpc) {
30-
this.logger = new Logger('AuthService');
30+
this.logger = new Logger(AuthGrpcService.name);
3131
}
3232

3333
onModuleInit() {

src/infrastructure/services/meeting/meeting.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class MeetingGrpcService implements OnModuleInit {
2727
private $reconnect: Subscription;
2828

2929
constructor(private readonly meetingClientProxy: ClientGrpc) {
30-
this.logger = new Logger('MeetingService');
30+
this.logger = new Logger(MeetingGrpcService.name);
3131
}
3232

3333
onModuleInit() {

src/infrastructure/services/sfu/domain/entities/track.ts

-24
This file was deleted.

0 commit comments

Comments
 (0)