how can i record a participants screen
# ask-ai
w
how can i record a participants screen
✅ 1
t
Thanks for reaching out, Steve. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I can help with that. You're asking how to record a participant's screen; below are the practical options and the typical steps to record a screen share using LiveKit's egress features. Which approach do you want to use? • Record only that participant's screen share (single participant, standalone file) → use Track Composite Egress. • Record the whole room or a layout that includes the participant's screen (multi-participant/scene) → use Room Composite Egress. If you want to record a single participant's screen, follow these steps: 1. Identify the participant’s track IDs ◦ Use your server SDK or ListParticipants API / webhooks to get the participant’s published tracks. ◦ Find the video track with source
screen_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):
Copy code
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 elements
w
i want to record participants screen and the audio of the room
t
Great — thanks for clarifying. You want to record a participant’s screen share video plus the audio from the whole room. That’s doable with LiveKit egress. Below I’ll outline the recommended approach and ask two quick questions so I can give you a precise code sample. Recommended approach • Use Track Composite Egress to record the participant’s screen-share video track. • For audio that contains the whole room (all participants), include the room-mixed audio track as the audio source. This produces a single file with the screen video and the room audio mixed together. • If you instead want a full layout (screen plus other video tiles), use Room Composite Egress with a layout that highlights the screen-share. Room Composite can also provide room-mixed audio. High-level steps 1. Find the track IDs ◦ Get the participant’s published tracks (via server SDK ListParticipants or webhooks). ◦ Identify the screen video track (source
screen_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 elements
w
i want the room audio mixed with screenshare
t
Thanks — I’ll help you set that up. To give a precise, runnable example for recording the screen share video with the room-mixed audio, I just need two quick details: 1. Which server SDK do you want the example in? (Node.js, Go, or Python) 2. What output format and destination do you want? Pick one: ◦ Single MP4 file (saved to S3/GCS or a local path) ◦ HLS ◦ RTMP stream Once you tell me those, I’ll provide the exact StartTrackCompositeEgress request (or Room Composite if you prefer a layout) and a code snippet you can run. If you already know the room and participant details, you can also share whether you want the recording to start automatically when the screen share starts or to be triggered manually. , with interactive elements
w
i need hls
t
Thanks — you want the participant's screen-share video combined with the room-mixed audio and output as HLS. I can give a concrete StartTrackCompositeEgress example for that. Before I provide the exact runnable code and request payload, which server SDK do you want the example in: Node.js, Go, or Python? Also, do you want the HLS saved to cloud storage (S3/GCS) or served from the LiveKit host/local path? If you pick S3/GCS, tell me which provider so I can include the output config. , with interactive elements
w
nocd.js
and s3
t
Thanks — I’ll give you a concrete Node.js example that starts a Track Composite Egress to record a participant’s screen-share video together with the room-mixed audio and output it as HLS to an S3 bucket. Before you run it, make sure you have: • Your LiveKit server egress client configured and authorized. • The room name and the screen-share video track ID (video track with source
screen_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.
Copy code
// 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 elements
w
how does this owrk can you tell me
t
Thanks — I’ll walk you through how the Node.js Track Composite Egress → HLS on S3 flow works, step by step, so you understand what happens end-to-end and how the code ties into each step. High-level flow • A participant publishes a screen-share video track into a LiveKit room. Other participants publish their audio/video as usual. • Your server calls LiveKit’s Egress service to create a Track Composite Egress that takes the screen-share video track plus a selected audio source and produces HLS segments and playlists. • LiveKit performs the mixing/encoding on the server side: it records the screen video track and mixes the chosen audio into a single output stream. • The encoder produces HLS output (segment files + index playlist). LiveKit uploads those HLS files to your configured S3 location. • You receive webhook events (egress_started, egress_ended) so you know when the HLS is available or when recording stops. Detailed steps and how to implement them 1) Identify the tracks you want to record • When a participant starts screen sharing, LiveKit creates a video track with source
screen_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