white-telephone-79320
03/23/2026, 6:57 AMtall-airline-16756
03/23/2026, 6:57 AMtall-airline-16756
03/23/2026, 6:57 AMscreen_share (this is the screen video). Also identify the related audio track ID if you want system or mic audio.
1. Start a Track Composite Egress
◦ Call the Egress API (server SDK) to start a Track Composite Egress and provide:
▪︎ RoomName — the room containing the participant.
▪︎ VideoTrackId — the screen share video track SID.
▪︎ AudioTrackId — optional, the associated audio track SID.
▪︎ Output — choose file (MP4/WebM/HLS) or streaming (RTMP), and set destination (S3/GCS/local).
◦ The recording will begin and produce a standalone file containing the screen and audio you specified.
Example (Go pseudocode):
info, err := egressClient.StartTrackCompositeEgress(ctx, &livekit.TrackCompositeEgressRequest{
RoomName: "your-room-name",
VideoTrackId: "video-screen-share-sid",
AudioTrackId: "audio-sid", // optional
Output: &livekit.TrackCompositeEgressRequest_File{
File: &livekit.EncodedFileOutput{
FileType: livekit.EncodedFileType_MP4,
Filepath: "recordings/screen-share-recording.mp4",
// add S3/GCS config if needed
},
},
})
1. Monitor and stop
◦ The egress runs until the track is unpublished or you call StopEgress with the returned EgressId.
◦ LiveKit emits egress_started and egress_ended webhooks so you can track status and do post-processing.
If you prefer to capture the full room with a layout that highlights the screen-sharer:
1. Use Room Composite Egress and choose or customize a layout (for example, a layout that places the screen-share prominently).
2. Start Room Composite Egress with the room name and layout settings. Output options are the same (MP4/HLS/RTMP/S3/GCS).
3. Monitor via webhooks and stop as needed.
Notes and tips
• Ensure the participant is allowed to publish (canPublish: true) and that the room type supports egress.
• Supported output formats: MP4, WebM, HLS; streaming via RTMP is supported.
• Backup storage for failed uploads can be enabled (if needed) and egress webhooks include flags/manifest locations if backup storage was used.
If you’d like, tell me:
• Which server SDK you’re using (Node, Go, Python, etc.), and
• Whether you want a single participant file or the whole-room layout,
and I’ll give a concrete code example and the exact request fields to use.
Sources: Universal Egress | LiveKit | examples/voice_agents | livekit/livekit_composite | DeepWiki | server-sdk-js | livekit/livekit_composite | DeepWiki | server-sdk-ruby | livekit/livekit_composite | DeepWiki | Backup Egress Recordings, with interactive elementswhite-telephone-79320
03/23/2026, 6:58 AMtall-airline-16756
03/23/2026, 6:58 AMscreen_share) — use that as VideoTrackId.
◦ Identify the room-mixed audio track or the published audio track you want to use as AudioTrackId. If you want truly all-room audio, use the room-mixed audio track provided by LiveKit egress (or supply the mixed audio track ID if available).
1. Start the egress
◦ Call StartTrackCompositeEgress with:
▪︎ RoomName
▪︎ VideoTrackId = screen share video track SID
▪︎ AudioTrackId = room-mixed audio track SID (or desired audio track)
▪︎ Output = file (MP4/WebM/HLS) or RTMP/S3/GCS destination
1. Monitor and stop
◦ Use the returned EgressId to stop if needed.
◦ Listen for egress_started and egress_ended webhooks to track status and retrieve file locations.
Questions so I can give exact code
1. Which server SDK do you want the example in? (Node.js, Go, or Python)
2. What output do you want? (single MP4 file, HLS, or RTMP stream; and do you want it saved to S3/GCS or a local path)
If you prefer Room Composite Egress instead (record room layout + room audio), tell me if you want a default layout or a custom one. Once you tell me SDK and output choice, I’ll provide a concrete request payload/code snippet you can run.
, with interactive elementswhite-telephone-79320
03/24/2026, 4:58 AMtall-airline-16756
03/24/2026, 4:58 AMwhite-telephone-79320
03/24/2026, 6:42 AMtall-airline-16756
03/24/2026, 6:42 AMwhite-telephone-79320
03/24/2026, 6:42 AMwhite-telephone-79320
03/24/2026, 6:42 AMtall-airline-16756
03/24/2026, 6:43 AMscreen_share). You can get track IDs via ListParticipants or via webhooks when participants publish tracks.
• An S3 bucket and credentials with write access. You’ll provide the S3 bucket name, region, and an object prefix for the HLS files.
Example: Node.js (Start Track Composite Egress -> HLS to S3)
1. Install the LiveKit server SDK if you haven’t already (Node package for server egress).
2. Use the following code template, replacing the placeholder values with your room name, video/audio track IDs, and S3 details.
// Example Node.js: start Track Composite Egress -> HLS stored on S3
// Replace placeholders with your actual values.
const { EgressClient } = require('livekit-server-sdk'); // adjust import if package name differs
const { TrackCompositeEgressRequest, EncodedFileOutput, HlsOutput, S3Output } = require('livekit-proto'); // adjust based on SDK
async function startScreenShareHlsEgress() {
// Configure client: use your LiveKit egress RPC endpoint and credentials
const egressHost = 'EGRESS_RPC_HOST:PORT'; // e.g., egress.livekit.example:50051
const apiKey = 'API_KEY';
const apiSecret = 'API_SECRET';
const client = new EgressClient(egressHost, apiKey, apiSecret);
const roomName = 'your-room-name';
const videoTrackId = 'screen-share-video-track-sid'; // track with source = screen_share
const audioTrackId = 'room-mixed-audio-track-sid'; // room-mixed audio track SID (or desired audio track)
// S3 configuration
const s3Region = 'us-east-1';
const s3Bucket = 'your-s3-bucket-name';
const s3Prefix = 'egress/hls/screen-share/room-name/'; // prefix/folder in bucket for HLS files
// Build HLS -> S3 output config
const hlsOutput = new HlsOutput({
// Playlist settings are optional; default segment length is OK, but you can set variant playlist options
// e.g., playlistName: 'index.m3u8', segmentDuration: 6
});
const s3Output = new S3Output({
region: s3Region,
bucket: s3Bucket,
// If you want a prefix/folder, set prefix
path: s3Prefix,
// Optionally provide access credentials here or rely on instance role / environment creds
// accessKey: 'AWS_ACCESS_KEY_ID',
// secretKey: 'AWS_SECRET_ACCESS_KEY',
});
// EncodedFileOutput is used by some SDKs for file outputs — for HLS we embed HlsOutput with S3Output
const request = new TrackCompositeEgressRequest({
roomName: roomName,
videoTrackId: videoTrackId,
audioTrackId: audioTrackId,
// Output as HLS to S3
output: {
hls: hlsOutput,
s3: s3Output,
},
// Optional: layout/template settings, resolution, etc.
// For screen recording, you may want to specify width/height or let it use defaults
});
try {
const response = await client.startTrackCompositeEgress(request);
console.log('Egress started:', response.egressId);
// Save response.egressId so you can stop it later if needed
} catch (err) {
console.error('Failed to start egress:', err);
}
}
startScreenShareHlsEgress();
Key points and tips
• Track IDs: Use ListParticipants or the participant-published webhook to find the screen-share track. The screen video track typically has source screen_share.
• Room-mixed audio: For a single mixed audio track ID, use the room-mixed audio track SID if available. If you don’t have a room-mixed track SID, LiveKit can mix audio for egress—provide the audio track you want or use Room Composite Egress to get built-in mixed audio.
• HLS on S3: You can provide S3 credentials in the request or rely on the environment (instance role or environment variables). Ensure the S3 path/prefix is writable and that CORS/permissions are set if you’ll serve the playlist directly from S3.
• Monitoring: LiveKit emits egress_started and egress_ended webhooks. Use them to know when the HLS playlist and segments are available or if a backup manifest is needed.
• Stopping: Keep the returned egressId to stop the egress via StopEgress when you want to end the recording.
If you want, I can:
• Provide a full copy-paste-ready Node.js example using the exact npm package names you use (tell me which LiveKit server SDK package you installed), or
• Convert this to a Room Composite Egress example if you prefer a layout that shows both the screen and participant tiles while still using mixed room audio.
Which would you like next?
, with interactive elementswhite-telephone-79320
03/24/2026, 6:44 AMtall-airline-16756
03/24/2026, 6:44 AMscreen_share. Your server can discover that track either:
◦ By calling the server API to list participants and their published tracks, or
◦ By listening to LiveKit webhooks/events that notify you when tracks are published.
• For the audio, you want “room-mixed” audio. Either:
◦ Use the room-mixed audio track SID if your LiveKit setup exposes one, or
◦ Let the egress service mix audio for the output (Track Composite Egress can accept an audio track ID or be configured to use mixed audio).
Why track IDs matter: the egress request points to exact track IDs so LiveKit knows which video and audio streams to mux together into the HLS output.
2) Start the Track Composite Egress (your server calls LiveKit)
• You construct a StartTrackCompositeEgress request with fields including:
◦ roomName: which room to read from
◦ videoTrackId: the screen-share video track SID
◦ audioTrackId: the room-mixed audio SID (or another audio track)
◦ output: specify HLS output and S3 storage details (bucket, region, path/prefix)
• When you call the Egress API, LiveKit responds with an egressId. Keep this ID if you want to stop the recording later.
What LiveKit does after you call Start:
• It attaches to the room and subscribes to the provided tracks (video and audio).
• It encodes and muxes the video with the provided/mixed audio into a single timeline.
• It segments the encoded stream into HLS segments and writes a playlist (index.m3u8) and associated .ts (or fMP4) segments.
3) HLS generation and storage to S3
• The egress encoder produces an HLS playlist and segments locally on the LiveKit host.
• LiveKit uploads those files to the S3 destination you specified in the egress request (bucket + prefix). You can provide AWS credentials in the request or rely on instance roles/environment credentials.
• The playlist URL will be the S3 object URL (or your CDN/website if you serve via CloudFront). Make sure S3 permissions/CORS allow the client to fetch the playlist if you’ll serve it directly.
4) Monitoring and lifecycle
• LiveKit emits egress_started and egress_ended webhooks. Use these to:
◦ Know when to start offering the HLS URL to viewers.
◦ Trigger post-processing, move files, or notify users when recording completes.
• If you need to stop the recording before the track is unpublished, call StopEgress with the egressId.
• If the upload to S3 fails, there’s an optional backup manifest behavior (enabled by support) so you can retrieve the recording later.
5) Playback and distribution
• Once on S3, the HLS playlist + segments are standard HLS assets. You can:
◦ Serve them directly from S3 (public or signed URLs).
◦ Put a CDN (CloudFront) in front of the bucket for lower latency and caching.
◦ Use the index.m3u8 URL in any HLS-compatible player.
How the Node.js code you were shown maps to this flow
• The code creates an Egress client and calls startTrackCompositeEgress with:
◦ The roomName, videoTrackId, audioTrackId fields (selects tracks to record).
◦ An HLS output configuration and S3 output config (tells LiveKit to produce HLS and upload to S3).
• The response contains egressId which you store if you want to stop the egress later or correlate with webhooks.
• Errors from the start call indicate problems like invalid track IDs, permission/credential problems for S3, or egress service errors.
Practical tips and gotchas
• Make sure the videoTrackId you pass is the screen-share track SID (source = screen_share). If you pass the wrong ID, egress will record the wrong video.
• Ensure the audioTrackId corresponds to the mixed room audio or another audio you want. If you don’t pass an audio track and want full-room audio, use Room Composite Egress or confirm that Track Composite supports room mixing in your setup.
• S3 permissions: grant write access for the credentials you use, and set correct ACLs or caching headers if you need public playback.
• HLS playlist timing: segments appear after the first few seconds (based on your segment duration). Use the egress_started webhook to know when the first playlist is available.
• Cost and storage: HLS produces multiple files; account for S3 storage and PUT request costs.
Next steps I can help with
• Provide a complete, copy-paste Node.js example using the exact npm package you installed (tell me the SDK package name you use), including where to plug in AWS credentials or how to use instance roles.
• Show how to list participants and get the screen-share track ID programmatically before starting egress.
• Provide an example of handling egress_started and egress_ended webhooks and mapping the S3 HLS URL for playback.
Which of those would you like next? If you want the runnable Node.js example, tell me the SDK package name (or I can assume the common server SDK) and whether you’ll supply AWS keys in the request or use instance role/environment credentials.
, with interactive elements