Skip to content

Commit d487d42

Browse files
[wip] recorder/task
Implement dynamic FFMPEG management for audio recording with explicit task events and standardized parameter handling.
1 parent 5bb85bc commit d487d42

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

src/models/ffmpeg.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { EventEmitter } from "node:events";
22

3+
let currentId = 0;
4+
35
export class FFMPEG extends EventEmitter {
6+
id: number;
47
constructor() {
58
super();
9+
this.id = currentId++ % 999999;
610
}
711

812
async kill() {}

src/models/recorder.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { EventEmitter } from "node:events";
22

33
import { getFolder, type Folder } from "#src/services/resources.ts";
4-
import { RecordingTask } from "#src/models/recording_task.ts";
4+
import { RecordingTask, type RecordingParameters } from "#src/models/recording_task.ts";
55
import { Logger } from "#src/utils/utils.ts";
66

77
import type { Channel } from "#src/models/channel";
@@ -130,14 +130,7 @@ export class Recorder extends EventEmitter {
130130
if (!session) {
131131
return;
132132
}
133-
this.tasks.set(
134-
session.id,
135-
new RecordingTask(session, {
136-
audio: this.isRecording || this.isTranscribing,
137-
camera: this.isRecording,
138-
screen: this.isRecording
139-
})
140-
);
133+
this.tasks.set(session.id, new RecordingTask(session, this._getTaskParameters()));
141134
}
142135

143136
private onSessionLeave(id: SessionId) {
@@ -173,10 +166,9 @@ export class Recorder extends EventEmitter {
173166
}
174167

175168
private async update() {
169+
const params = this._getTaskParameters();
176170
for (const task of this.tasks.values()) {
177-
task.audio = this.isRecording || this.isTranscribing;
178-
task.camera = this.isRecording;
179-
task.screen = this.isRecording;
171+
Object.assign(task, params);
180172
}
181173
}
182174

@@ -185,10 +177,7 @@ export class Recorder extends EventEmitter {
185177
this.folder = getFolder();
186178
logger.trace(`TO IMPLEMENT: recording channel ${this.channel.name}`);
187179
for (const [sessionId, session] of this.channel.sessions) {
188-
this.tasks.set(
189-
sessionId,
190-
new RecordingTask(session, { audio: true, camera: true, screen: true })
191-
);
180+
this.tasks.set(sessionId, new RecordingTask(session, this._getTaskParameters()));
192181
}
193182
this.channel.on("sessionJoin", this.onSessionJoin);
194183
this.channel.on("sessionLeave", this.onSessionLeave);
@@ -202,4 +191,12 @@ export class Recorder extends EventEmitter {
202191
this.tasks.clear();
203192
return Promise.allSettled(proms);
204193
}
194+
195+
private _getTaskParameters(): RecordingParameters {
196+
return {
197+
audio: this.isRecording || this.isTranscribing,
198+
camera: this.isRecording,
199+
screen: this.isRecording
200+
};
201+
}
205202
}

src/models/recording_task.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@ import { FFMPEG } from "#src/models/ffmpeg.ts";
77

88
import type { PlainTransport } from "mediasoup/node/lib/PlainTransportTypes";
99

10+
export type RecordingParameters = {
11+
audio: boolean;
12+
camera: boolean;
13+
screen: boolean;
14+
};
15+
16+
export enum RECORDING_TASK_EVENT {
17+
AUDIO_STARTED = "audio-started",
18+
AUDIO_STOPPED = "audio-stopped",
19+
CAMERA_STARTED = "camera-started",
20+
CAMERA_STOPPED = "camera-stopped",
21+
SCREEN_STARTED = "screen-started",
22+
SCREEN_STOPPED = "screen-stopped"
23+
}
24+
1025
const logger = new Logger("RECORDING_TASK");
1126

1227
export class RecordingTask extends EventEmitter {
@@ -37,8 +52,14 @@ export class RecordingTask extends EventEmitter {
3752
`TO IMPLEMENT: recording task for session ${this.session.id} - audio: ${value}`
3853
);
3954
logger.debug(`rtp: ${this._audioRTP}, ffmpeg: ${this._audioFFFMPEG}`);
40-
// await record(audio)
41-
// if (this.isStopped) { cleanup(audio) };
55+
if (this._audio) {
56+
this._audioFFFMPEG = new FFMPEG(); // should take RTP info as param
57+
this.emit(RECORDING_TASK_EVENT.AUDIO_STARTED, this._audioFFFMPEG.id);
58+
} else if (this._audioFFFMPEG) {
59+
this.emit(RECORDING_TASK_EVENT.AUDIO_STOPPED, this._audioFFFMPEG.id);
60+
this._audioFFFMPEG.kill();
61+
this._audioFFFMPEG = undefined;
62+
}
4263
}
4364
set camera(value: boolean) {
4465
if (value === this._camera || this.isStopped) {
@@ -61,10 +82,7 @@ export class RecordingTask extends EventEmitter {
6182
logger.debug(`rtp: ${this._screenRTP}, ffmpeg: ${this._screenFFMPEG}`);
6283
}
6384

64-
constructor(
65-
session: Session,
66-
{ audio, camera, screen }: { audio?: boolean; camera?: boolean; screen?: boolean } = {}
67-
) {
85+
constructor(session: Session, { audio, camera, screen }: RecordingParameters) {
6886
super();
6987
this.session = session;
7088
this._audio = audio ?? false;

0 commit comments

Comments
 (0)