Integrate LiveKit SFU and harden booking workflow
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { createHmac } from "node:crypto";
|
||||
import { AccessToken, RoomServiceClient, TrackSource } from "livekit-server-sdk";
|
||||
import type { MeetingRole } from "./token";
|
||||
|
||||
function requiredEnv(name: "LIVEKIT_URL" | "LIVEKIT_API_KEY" | "LIVEKIT_API_SECRET"): string {
|
||||
const value = process.env[name];
|
||||
if (!value) throw new Error(`${name} is not set`);
|
||||
return value;
|
||||
}
|
||||
|
||||
export function getLiveKitClientUrl(): string {
|
||||
return requiredEnv("LIVEKIT_URL").replace(/^http:/, "ws:").replace(/^https:/, "wss:").replace(/\/$/, "");
|
||||
}
|
||||
|
||||
function getLiveKitApiUrl(): string {
|
||||
return requiredEnv("LIVEKIT_URL").replace(/^ws:/, "http:").replace(/^wss:/, "https:").replace(/\/$/, "");
|
||||
}
|
||||
|
||||
/** Stable opaque room name; the public event slug is never sent to LiveKit logs. */
|
||||
export function getLiveKitRoomName(eventSlug: string): string {
|
||||
const secret = requiredEnv("LIVEKIT_API_SECRET");
|
||||
return `anouma-${createHmac("sha256", secret).update(eventSlug).digest("hex").slice(0, 32)}`;
|
||||
}
|
||||
|
||||
export async function createLiveKitToken(args: {
|
||||
eventSlug: string;
|
||||
participantId: string;
|
||||
name: string;
|
||||
role: MeetingRole;
|
||||
clientId?: string;
|
||||
}): Promise<string> {
|
||||
const room = getLiveKitRoomName(args.eventSlug);
|
||||
const token = new AccessToken(requiredEnv("LIVEKIT_API_KEY"), requiredEnv("LIVEKIT_API_SECRET"), {
|
||||
identity: args.participantId,
|
||||
name: args.name,
|
||||
ttl: "2h",
|
||||
metadata: JSON.stringify({ role: args.role, clientId: args.clientId }),
|
||||
});
|
||||
token.addGrant({
|
||||
roomJoin: true,
|
||||
room,
|
||||
canPublish: true,
|
||||
canSubscribe: true,
|
||||
canPublishData: true,
|
||||
canPublishSources: args.role === "host"
|
||||
? [TrackSource.CAMERA, TrackSource.MICROPHONE, TrackSource.SCREEN_SHARE, TrackSource.SCREEN_SHARE_AUDIO]
|
||||
: [TrackSource.CAMERA, TrackSource.MICROPHONE],
|
||||
});
|
||||
return token.toJwt();
|
||||
}
|
||||
|
||||
export function getLiveKitRoomService(): RoomServiceClient {
|
||||
return new RoomServiceClient(getLiveKitApiUrl(), requiredEnv("LIVEKIT_API_KEY"), requiredEnv("LIVEKIT_API_SECRET"));
|
||||
}
|
||||
Reference in New Issue
Block a user