Hi LiveKit team :wave: I’m stuck with an issue rel...
# egress
g
Hi LiveKit team 👋 I’m stuck with an issue related to room composite recording (egress) and could use some guidance. Problem: I’m recording a room using RoomCompositeEgress. Recordings are successfully uploaded to Cloudflare R2 (S3-compatible) When screen share or camera is ON, the recording looks fine • But when no screen share or camera is active, the recorded video shows a black screen What I’m expecting instead is: • A default participant tile / placeholder UI (similar to what the LiveKit UI shows when users are audio-only) Current behavior: • Live room UI works fine • Recording shows black frames until someone shares screen or turns on camera What I want: • Always show a grid / participant tile layout even when users are audio-only • Avoid black screen in the recording Current egress implementation:
Copy code
export 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 🙏
c
Hey @glamorous-garden-97700 - I think this is indeed expected behavior of the default template. Custom recording view/template would be the way to go
g
Hey @clever-nail-49292, thanks for confirming 🙌 Just wanted to check that I'm on the right path. Based on your reply, I went ahead with a custom recording layout using
customBaseUrl
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 far
c
as long as you follow the approach outlined in the default template - don't see the reason why this won't work. Few details to pay attention to: Your custom page needs to: 1. Parse URL parameters for connection details:
Copy code
const 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:
Copy code
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