hundreds-energy-79975
04/09/2026, 8:39 PMTrackCompositeEgress with ingress track IDs ✅ works perfectly
2. Internal — Host shares browser tab (scene URL) via WebRTC screen share → we want to use TrackCompositeEgress but facing issues
Current Problem: For internal streaming, we currently use WebEgress which opens our display page (/display) in a headless browser. This causes duplicate audio — the display page plays participant audio AND the host hears it echoed back through their screen share capture.
What We Tried: We want to switch internal streaming to TrackCompositeEgress to avoid the headless browser and duplicate audio issue. However:
When stream starts, the host may not have published their screen share tracks yet — so TrackCompositeEgress fails with invalid_argument: audio_track_id or video_track_id missing
We tested passing nil for track IDs — LiveKit returns invalid_argument — so empty track IDs are not supported
1. We need the egress to capture screen share audio + video when host starts screen sharing, and fall back to mic + camera when not sharing
Questions:
Is there a way to create TrackCompositeEgress without specifying track IDs upfront and have LiveKit auto-select tracks as they are published?
Is there a track_published webhook event we can listen to so we can create egress after the host publishes their screen share tracks?
1. Can we update an existing TrackCompositeEgress to swap track IDs when the host switches between camera and screen share?
2. What is the recommended approach for capturing a host's screen share + audio for streaming to RTMP when tracks are published after egress creation?
Tech Stack: Ruby on Rails backend, LiveKit Ruby SDK, Next.js frontend, LiveKit JS SDKtall-airline-16756
04/09/2026, 8:39 PMtall-airline-16756
04/09/2026, 8:39 PMinvalid_argument.
• LiveKit does not auto-select tracks for an existing TrackCompositeEgress, and you cannot update an active TrackCompositeEgress to swap track IDs.
• There is a track_published webhook you can listen to. Use it to detect when the host publishes screen-share (video and/or screen audio).
Recommended pattern for your use case
1. Start no egress initially (avoid WebEgress) or leave any egress stopped.
2. Subscribe to track_published webhooks for the room.
3. When you receive track_published for the host’s screen-share tracks (identify by track kind or metadata indicating SCREEN_SHARE):
◦ Create a TrackCompositeEgress using those screen-share track IDs (audio/video) so the egress captures screen audio+video directly — no headless browser needed.
1. If the host hasn’t published screen share and you must start streaming immediately:
◦ Create TrackCompositeEgress using mic+camera track IDs (host’s published tracks) as a fallback.
◦ When a screen-share track_published arrives, stop the current egress and start a new TrackCompositeEgress with the screen-share track IDs (since you cannot swap IDs on a running egress).
1. To minimize downtime when switching, pre-plan logic to quickly stop/start egresses and keep RTMP destination consistent (same RTMP target) so the transition is fast and transparent on YouTube.
Implementation notes for your stack
• Use the LiveKit Ruby SDK on your Rails backend to:
◦ Receive and validate track_published webhooks.
◦ Look up the published track IDs for that participant (room/participant/track info) and then call TrackCompositeEgress creation with those IDs.
• On Next.js/LiveKit JS, ensure you set clear track metadata or identify screen-share tracks by `source`/`name` so server-side logic can reliably detect screen-share vs camera/mic.
• Stopping and restarting egress is the practical way to swap inputs because active egress config is immutable.
If helpful, I can:
• Provide a concise Rails webhook handler example that detects screen-share tracks and calls the Ruby SDK to start TrackCompositeEgress.
• Sketch the minimal fallback flow (start with mic+cam, replace with screen-share on publish) including the exact webhook fields to check. Which would you prefer? Sources: Universal Egress | LiveKit | server-sdk-js | livekit/livekit_composite | DeepWiki | Best practices for managing webhook event streams | LiveKit | Server-side | livekit/livekit_composite | DeepWiki, with interactive elementshundreds-energy-79975
04/09/2026, 8:42 PMtall-airline-16756
04/09/2026, 8:42 PMtrack_published for screen-share, then stop/start TrackCompositeEgress quickly. Keep the same RTMP target to reduce visible transitions; optimize for minimal downtime.
Questions to pick the best path:
• Do you need selective per-participant composition (only host), or is capturing the entire room acceptable?
• Can you run a small mixing process (client or server-side bot), or must all logic stay purely server-side without extra participants?
Tell me which constraints apply and I’ll give a focused implementation sketch (Rails webhook + Ruby SDK, or a small muxer design).
, with interactive elementshundreds-energy-79975
04/09/2026, 8:46 PMRoomCompositeEgress with a custom layout URL the most suitable option.
Updated preferred approach:
RoomCompositeEgress with custom layout URL — if it supports providing our own display page URL (like WebEgress does), this would be perfect because:
• No track ID management needed
• Captures the full scene with all overlays and elements
• No duplicate audio since it's a separate headless browser context
• Handles any participant's screen share automatically
• No stop/start needed when participants switch between camera and screen share
Key question: Can RoomCompositeEgress accept a custom layout URL (our scene display page at <https://our-domain.com/display/:uuid>) similar to how WebEgress works? If yes, this solves all our problems cleanly. If not, what is the recommended way to stream a custom scene layout that includes multiple participants' tracks, overlays, and dynamic elements to RTMP?tall-airline-16756
04/09/2026, 8:47 PMhttps://our-domain.com/display/:uuid) in the same way WebEgress does.
• RoomCompositeEgress uses the Egress Template SDK: you must provide a template (hosted for the egress service) that implements your layout logic. The egress service runs the template in a headless browser and captures the composed output.
• WebEgress is the feature that captures a supplied web page URL directly, but RoomCompositeEgress won’t load your Rails page by URL.
What that means for your requirements
• If you need the exact Rails-rendered page (your scene HTML/CSS/JS) captured as-is, WebEgress is the intended match because it accepts a page URL. If WebEgress supports RTMP in your environment, it solves your needs directly.
• If you must use RoomCompositeEgress (for RTMP support or other reasons), you’ll need to reproduce your scene within an Egress Template. The template can:
◦ Render multiple participant tracks, screen shares, overlays, banners, and dynamic layouts.
◦ Be driven by the same data/logic you use in your Rails page, but implemented inside the template (web code run by the egress service).
◦ Capture any participant’s screen share automatically because it subscribes to room tracks.
Alternatives and trade-offs
• WebEgress (capture your actual display URL): Easiest to preserve exact Rails rendering and page logic. Confirm whether your deployment’s WebEgress supports RTMP output if RTMP is required.
• RoomCompositeEgress + Egress Template SDK: More work to port your scene into the template, but offers server-managed composition and is compatible with RoomComposite workflows (and captures screen shares and overlays via template logic).
• Hybrid: Replicate only the dynamic composition parts in the template (reuse components) and keep nonessential UI in Rails to minimize porting.
Recommended next step (pick one)
• If capturing the Rails page exactly is highest priority: try WebEgress for the display URL and verify RTMP support in your environment.
• If RTMP support requires RoomCompositeEgress or you want the egress to control composition: plan to port the scene into an Egress Template. I can help sketch how to map your Rails components to a template (track placement, overlay injection, layout rules).
Which path do you prefer — test WebEgress for RTMP, or get a template-sketch to port your Rails scene into RoomCompositeEgress?
Sources: Universal Egress | LiveKit | server-sdk-js | livekit/livekit_composite | DeepWiki, with interactive elements