Skip to content

Commit f64b870

Browse files
[IMP] rec addr
1 parent 19047dc commit f64b870

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

src/models/channel.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ interface ChannelCreateOptions {
5353
key?: string;
5454
/** Whether to enable WebRTC functionality */
5555
useWebRtc?: boolean;
56-
useRecording?: boolean;
56+
recordingAddress?: string | null;
5757
}
5858
interface JoinResult {
5959
/** The channel instance */
@@ -105,7 +105,7 @@ export class Channel extends EventEmitter {
105105
issuer: string,
106106
options: ChannelCreateOptions = {}
107107
): Promise<Channel> {
108-
const { key, useWebRtc = true, useRecording = true } = options;
108+
const { key, useWebRtc = true, recordingAddress } = options;
109109
const safeIssuer = `${remoteAddress}::${issuer}`;
110110
const oldChannel = Channel.recordsByIssuer.get(safeIssuer);
111111
if (oldChannel) {
@@ -115,7 +115,7 @@ export class Channel extends EventEmitter {
115115
const channelOptions: ChannelCreateOptions & {
116116
worker?: Worker;
117117
router?: Router;
118-
} = { key, useRecording: useWebRtc && useRecording };
118+
} = { key, recordingAddress: useWebRtc ? recordingAddress : null };
119119
if (useWebRtc) {
120120
channelOptions.worker = await getWorker();
121121
channelOptions.router = await channelOptions.worker.createRouter({
@@ -186,7 +186,7 @@ export class Channel extends EventEmitter {
186186
const now = new Date();
187187
this.createDate = now.toISOString();
188188
this.remoteAddress = remoteAddress;
189-
this.recorder = config.recording.enabled && options.useRecording ? new Recorder(this) : undefined;
189+
this.recorder = config.recording.enabled && options.recordingAddress ? new Recorder(this, options.recordingAddress) : undefined;
190190
this.key = key ? Buffer.from(key, "base64") : undefined;
191191
this.uuid = crypto.randomUUID();
192192
this.name = `${remoteAddress}*${this.uuid.slice(-5)}`;
@@ -291,6 +291,7 @@ export class Channel extends EventEmitter {
291291
* @fires Channel#close
292292
*/
293293
close(): void {
294+
this.recorder?.stop();
294295
for (const session of this.sessions.values()) {
295296
session.off("close", this._onSessionClose);
296297
session.close({ code: SESSION_CLOSE_CODE.CHANNEL_CLOSED });

src/models/recorder.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ export class Recorder extends EventEmitter {
88
channel: Channel;
99
state: "started" | "stopped" = "stopped";
1010
ffmpeg = null;
11+
/** Path to which the final recording will be uploaded to */
12+
recordingAddress: string;
1113

12-
constructor(channel: Channel) {
14+
constructor(channel: Channel, recordingAddress: string) {
1315
super();
1416
this.channel = channel;
17+
this.recordingAddress = recordingAddress;
1518
}
1619

1720
async start() {

src/services/http.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,29 @@ function setupRoutes(routeListener: RouteListener): void {
7979
return res.end(JSON.stringify(channelStats));
8080
}
8181
});
82+
/**
83+
* GET /v1/channel
84+
*
85+
* Creates (or reuses) a media channel for the authenticated client.
86+
*
87+
* ### Headers
88+
* - `Authorization: Bearer <JWT>` — required.
89+
* The JWT must include the `iss` (issuer) claim identifying the caller.
90+
*
91+
* ### Query Parameters
92+
* - `webRTC` — optional, defaults to `"true"`.
93+
* When set to `"false"`, disables WebRTC setup and creates a non-media channel.
94+
* - `recordingAddress` — optional.
95+
* If provided, enables recording and specifies the destination address
96+
* for recorded media streams. This address should most likely include a secret token,
97+
* so that it can be used publicly. For example http://example.com/recording/123?token=asdasdasdasd
98+
*
99+
* ### Responses
100+
* - `200 OK` — returns `{ uuid: string, url: string }`
101+
* - `401 Unauthorized` — missing or invalid Authorization header
102+
* - `403 Forbidden` — missing `iss` claim
103+
* - `500 Internal Server Error` — failed to create the channel
104+
*/
82105
routeListener.get(`/v${API_VERSION}/channel`, {
83106
callback: async (req, res, { host, protocol, remoteAddress, searchParams }) => {
84107
try {
@@ -99,7 +122,7 @@ function setupRoutes(routeListener: RouteListener): void {
99122
const channel = await Channel.create(remoteAddress, claims.iss, {
100123
key: claims.key,
101124
useWebRtc: searchParams.get("webRTC") !== "false",
102-
useRecording: searchParams.get("recording") !== "false"
125+
recordingAddress: searchParams.get("recordingAddress")
103126
});
104127
res.setHeader("Content-Type", "application/json");
105128
res.statusCode = 200;

0 commit comments

Comments
 (0)