glamorous-garden-97700
12/23/2025, 4:24 PMexport async function startRoomRecording(roomName: string): Promise<void> {
const egressClient = getEgressClient();
const filepath = `${roomName}.mp4`;
const fileOutput = new EncodedFileOutput({
filepath,
output: {
case: "s3",
value: new S3Upload({
endpoint: R2_ENDPOINT,
accessKey: R2_KEY_ID,
secret: R2_KEY_SECRET,
region: R2_REGION,
bucket: R2_BUCKET,
forcePathStyle: true,
}),
},
});
await egressClient.startRoomCompositeEgress(roomName, fileOutput, {
layout: "grid",
});
}
Questions:
1. Is the black screen expected behavior when no video tracks are published?
2. Is there a way to force a default tile / placeholder in recordings?
3. Do we need a custom layout or video track injection for this use case?
Everything else in our recording flow works perfectly — this is the only blocker.
Thanks in advance 🙏clever-nail-49292
12/25/2025, 3:29 PMglamorous-garden-97700
12/29/2025, 10:53 AMcustomBaseUrl from this Egress Docs:
• Built a separate static HTML/CSS/JS recording UI that connects to the room via LiveKit JS SDK
• This layout renders participant tiles even when users are audio-only (avatar + name), so no black frames
• When camera or screenshare is published, it swaps to video
• Hosted it on a separate domain (<http://record.example.com|record.example.com>) and point egress to it
• Egress launches headless Chromium → loads this page → records the rendered output
Just wanted to check:
• Does the HTML+CSS+JS works?(it didn't work so far)
• I've also tried the react code from this repo and it didn't work well as my backend is not communicating with the recording URL. [docs]
Current Tech Stack:
frontend: Nextjs v14 (using from livekit example)
backend: express.js + pnpm (node)
Appreciate the guidance so farclever-nail-49292
12/30/2025, 5:57 PMconst url = getURLParam('url'); // LiveKit WebSocket URL
const token = getURLParam('token'); // Access token
const layout = getURLParam('layout'); // Layout name
2. Connect to the room using LiveKit JS SDK with those parameters
3. Signal recording lifecycle via console events:
console.log('START_RECORDING'); // Begin recording
console.log('END_RECORDING'); // End recording
You could also try sharing a few egressIDs where you experience the issue - we can check out logs and see what's going on if you don't figure it out in a meantime