Skip to content

Commit 659892f

Browse files
[IMP] wip
1 parent 10432af commit 659892f

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

src/config.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ export const HTTP_INTERFACE: string = process.env.HTTP_INTERFACE || "0.0.0.0";
6565
export const PORT: number = Number(process.env.PORT) || 8070;
6666

6767
/**
68-
* Whether the recording feature is enabled, true by default.
68+
* Whether the recording feature is enabled, false by default.
6969
*/
70-
export const RECORDING: boolean = !FALSY_INPUT.has(process.env.RECORDING!);
70+
export const RECORDING: boolean = Boolean(process.env.RECORDING);
7171

7272
/**
7373
* The number of workers to spawn (up to core limits) to manage RTC servers.
@@ -215,6 +215,7 @@ export const recording = Object.freeze({
215215
screenLimit: 1,
216216
});
217217

218+
// TODO: This should probably be env variable, and at least documented so that deployment can open these ports.
218219
export const dynamicPorts = Object.freeze({
219220
min: 50000,
220221
max: 59999,

src/models/recorder.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,29 @@ export class Recorder extends EventEmitter {
3232
logger.trace("TO IMPLEMENT");
3333
// TODO ffmpeg instance creation for recording to destPath with proper name, start, build timestamps object
3434
}
35-
35+
this._record();
3636
return { state: this.state };
3737
}
3838

3939
async stop() {
4040
if (this.state === RECORDER_STATE.STARTED) {
41-
4241
logger.trace("TO IMPLEMENT");
4342
this.emit("stopped");
4443
// TODO ffmpeg instance stop, cleanup,
4544
// only resolve promise and switch state when completely ready to start a new recording.
4645
this.state = RECORDER_STATE.STOPPED;
4746
}
48-
4947
return { state: this.state };
5048
}
49+
50+
/**
51+
* @param video whether we want to record videos or not (will always record audio)
52+
*/
53+
_record(video: boolean = false) {
54+
console.trace(`TO IMPLEMENT: recording channel ${this.channel.name}, video: ${video}`);
55+
// iterate all producers on all sessions of the channel, create a ffmpeg for each,
56+
// save them on a map by session id+type.
57+
// check if recording for that session id+type is already in progress
58+
// add listener to the channel for producer creation (and closure).
59+
}
5160
}

src/services/resources.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import type { WebRtcServerOptions } from "mediasoup/node/lib/types";
33

44
import * as config from "#src/config.ts";
55
import { Logger } from "#src/utils/utils.ts";
6+
import { PortLimitReachedError } from "#src/utils/errors.ts";
7+
import os from "node:os";
8+
9+
const availablePorts: Set<number> = new Set();
610

711
export interface RtcWorker extends mediasoup.types.Worker {
812
appData: {
@@ -12,6 +16,7 @@ export interface RtcWorker extends mediasoup.types.Worker {
1216

1317
const logger = new Logger("RESOURCES");
1418
const workers = new Set<RtcWorker>();
19+
const tempDir = os.tmpdir() + "/ongoing_recordings";
1520

1621
export async function start(): Promise<void> {
1722
logger.info("starting...");
@@ -22,6 +27,10 @@ export async function start(): Promise<void> {
2227
logger.info(
2328
`transport(RTC) layer at ${config.PUBLIC_IP}:${config.RTC_MIN_PORT}-${config.RTC_MAX_PORT}`
2429
);
30+
for (let i = config.dynamicPorts.min; i <= config.dynamicPorts.max; i++) {
31+
availablePorts.add(i);
32+
}
33+
logger.info(`${availablePorts.size} dynamic ports available [${config.dynamicPorts.min}-${config.dynamicPorts.max}]`);
2534
}
2635

2736
export function close(): void {
@@ -78,18 +87,26 @@ export async function getWorker(): Promise<mediasoup.types.Worker> {
7887
}
7988

8089
export function getFolder() {
81-
// create a temp folder at a path, returns the path and a function to seal the folder
90+
const tempName = `${Date.now()}`;
91+
const path = `${tempDir}/${tempName}`;
92+
// TODO we may want to track these temp folders to remove them periodically (although os.tempDir() has already such a mechanism)
8293
return {
83-
path: "",
84-
sealFolder: () => {
85-
// move the content into a permanent folder location so it can easily be retrieved for processing later
86-
// or directly forward for transcription
94+
path,
95+
sealFolder: (name: string = tempName) => {
96+
// TODO move whatever is in path to
97+
console.log(`${config.recording.directory}/${name}`);
8798
},
8899
}
89100
}
90101

91-
export function getPort() {
102+
export function getPort(): number {
103+
const port = availablePorts.values().next().value;
104+
if (!port) {
105+
throw new PortLimitReachedError();
106+
}
107+
return port;
92108
}
93109

94110
export function releasePort(port: number) {
111+
availablePorts.add(port);
95112
}

src/utils/errors.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ export class AuthenticationError extends Error {
55
export class OvercrowdedError extends Error {
66
name = "OvercrowdedError";
77
}
8+
9+
export class PortLimitReachedError extends Error {
10+
name = "PortLimitReachedError";
11+
}

0 commit comments

Comments
 (0)