Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
126 lines (103 loc) · 3.81 KB
/
Copy pathindex.js
File metadata and controls
126 lines (103 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { RTMSManager } from '../../library/javascript/rtmsManager/RTMSManager.js';
import WebhookManager from '../../library/javascript/webhookManager/WebhookManager.js';
import { tensorFlowDetectObject } from './tensorFlowDetectObject.js';
import { H264FrameDecoder } from './ffmpegFrameDecoder.js';
import dotenv from 'dotenv';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import express from 'express';
import { closeHttpServer, installGracefulShutdown } from '../../library/javascript/commonHelpers/gracefulShutdown.js';
import http from 'http';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
dotenv.config({ path: path.join(__dirname, '.env') });
const { MEDIA_PARAMS } = RTMSManager;
const decoderMap = new Map();
function sanitizeFileName(name) {
return name.replace(/[<>:"\/\\|?*=\s]/g, '_');
}
const appConfig = {
port: process.env.PORT || 3000,
};
const rtmsConfig = {
logging: {
enabled: true,
logDir: path.join(__dirname, 'logs'),
console: true
},
mediaTypesFlag: 2,
credentials: {
meeting: {
clientId: process.env.ZOOM_CLIENT_ID,
clientSecret: process.env.ZOOM_CLIENT_SECRET,
zoomSecretToken: process.env.ZOOM_SECRET_TOKEN,
}
},
mediaParams: {
video: {
codec: MEDIA_PARAMS.MEDIA_PAYLOAD_TYPE_H264,
resolution: MEDIA_PARAMS.MEDIA_RESOLUTION_HD,
fps: 25,
}
}
};
console.log('[detect_object] App Configuration:', appConfig);
console.log('[detect_object] RTMS Configuration:', RTMSManager.redactSecrets(rtmsConfig));
const app = express();
const server = http.createServer(app);
await RTMSManager.init(rtmsConfig);
const webhookManager = new WebhookManager({
config: {
webhookPath: process.env.WEBHOOK_PATH || '/webhook',
zoomSecretToken: rtmsConfig.credentials.meeting.zoomSecretToken,
},
app: app
});
webhookManager.on('event', (event, payload) => {
console.log('[detect_object] Webhook Event:', event);
RTMSManager.handleEvent(event, payload);
});
webhookManager.setup();
RTMSManager.on('video', (payload) => {
const { buffer, userId, userName, timestamp, meetingId } = payload;
const safeUserName = userName ? sanitizeFileName(userName) : 'default-view';
const safeMeetingUuid = sanitizeFileName(meetingId);
const outputDir = path.join(__dirname, 'recordings', safeMeetingUuid);
fs.mkdirSync(outputDir, { recursive: true });
if (!decoderMap.has(safeUserName)) {
const decoder = new H264FrameDecoder(outputDir, (imagePath, metadata) => {
const imgBuffer = fs.readFileSync(imagePath);
tensorFlowDetectObject(imgBuffer, safeUserName, metadata.timestamp, safeMeetingUuid, false);
});
decoderMap.set(safeUserName, decoder);
}
decoderMap.get(safeUserName).writeChunk(buffer, { timestamp });
});
RTMSManager.on('meeting.rtms_started', (payload) => {
console.log('[detect_object] RTMS Started:', payload.meeting_uuid);
});
RTMSManager.on('meeting.rtms_stopped', (payload) => {
console.log('[detect_object] RTMS Stopped:', payload.meeting_uuid);
for (const [key, decoder] of decoderMap.entries()) {
decoder.close();
}
decoderMap.clear();
});
RTMSManager.on('error', (error) => {
console.error('[detect_object] RTMSManager error:', error.message);
if (error.code) console.error('[detect_object] Error code:', error.code);
});
await RTMSManager.start();
server.listen(appConfig.port, () => {
console.log(`[detect_object] Server listening on port ${appConfig.port}`);
console.log(`[detect_object] Webhook endpoint: http://localhost:${appConfig.port}${process.env.WEBHOOK_PATH || '/webhook'}`);
});
installGracefulShutdown({ name: 'detect_object', cleanup: async () => {
for (const decoder of decoderMap.values()) {
decoder.close();
}
decoderMap.clear();
await closeHttpServer(server);
await RTMSManager.stop();
} });