Egress Overview

Use LiveKit's egress service to record or livestream a Room.

Introduction

LiveKit Egress gives you a powerful and consistent set of APIs to export any room or individual tracks from a LiveKit session.

It supports recording to a MP4 file or HLS segments, as well as exporting to livestreaming services like YouTube Live, Twitch, and Facebook via RTMP(s).

For LiveKit Cloud customers, Egress is ready to use with your project without additional configuration. When self-hosting LiveKit, Egress is a separate component that needs to be deployed.

Egress Types

Room Composite Egress

Export an entire room's video and/or audio using a web layout rendered by Chrome.

Example use case: recording a meeting for team members to watch later.

Track Composite Egress

Sync and export up to one audio and one video track. Will transcode and mux.

Example use case: exporting audio+video from many cameras at once during a production, for use in additional post-production.

Track Egress

Export individual tracks directly. Video tracks are not transcoded.

Example use case: streaming an audio track to a captioning service via websocket.

Supported Outputs

Egress TypeMP4 FileOGG FileWebM FileHLS (TS SEGMENTS)RTMP(s) StreamWebSocket StreamThumbnails (JPEGs)
Room Composite
Web
Track Composite
Track

Files can be uploaded to any S3 compatible storage, Azure, GCP, or Ali OSS.

Note that a very long-running Egress may hit our Egress time limits.

Multi-output

Egress is optimized to transcode once while sending output to multiple destinations. For example, from the same Egress you may simultaneously

  • stream to multiple RTMP endpoints
  • record as HLS
  • record as MP4
  • generate thumbnails

Streaming

RTMP streams can be added and removed on the fly using the UpdateStream API.

Streaming to Mux

To start a Mux stream, all you need is your stream key. You can then use mux://<stream_key> as a url in your StreamOutput.

Choosing RTMP ingest endpoints

RTMP streams do not perform well over long distances. Some stream providers include a region or location as part of your stream url, while others might use region-based routing.

  • When self-hosting, choose stream endpoints that are close to where your Egress servers are deployed.
  • With Cloud Egress, we will route your egress request to a server closest to your rtmp endpoints. If streaming to multiple destinations, it is best to choose endpoints which are close to one another.

Adding streams to non-streaming egress

In order to use the UpdateStream API, your initial request will need to contain a StreamOutput. This means if you want to start a file recording first and then add streams afterwards, the initial request will need to contain a StreamOutput with protocol set to RTMP and urls left empty.

Websocket streams

The Egress service will send pings to your websocket server every 30 seconds. Your server should both respond to these pings, and send pings of its own to avoid timeouts and other abnormal closures.

File/Segment outputs

Filename templating

The below templates can be used in request filename/filepath parameters:

Egress Type{room_id}{room_name}{time}{publisher_identity}{track_id}{track_type}{track_source}
Room Composite
Web
Track Composite
Track
  • If no filename is provided with a request, one will be generated in the form of "{room_name}-{time}".
  • If your filename ends with a /, a file will be generated in that directory.
  • If your filename is missing an extension or includes the wrong extension, the correct one will be added.

Examples:

Request filenameOutput filename
""testroom-2022-10-04T011306.mp4
"livekit-recordings/"livekit-recordings/testroom-2022-10-04T011306.mp4
"{room_name}/{time}"testroom/2022-10-04T011306.mp4
"{room_id}-{publisher_identity}.mp4"10719607-f7b0-4d82-afe1-06b77e91fe12-david.mp4
"{track_type}-{track_source}-{track_id}"audio-microphone-TR_SKasdXCVgHsei.ogg

S3

Egress supports any S3-compatible storage provider. When endpoint is left empty, it'll use AWS's regional endpoints. region is required when endpoint is not set.

const fileOutput = new EncodedFileOutput({
fileType: EncodedFileType.MP4,
filepath: 'livekit-demo/room-composite-test.mp4',
output: {
case: 's3',
value: new S3Upload({
accessKey: 'aws-access-key',
secret: 'aws-access-secret',
bucket: 'my-bucket',
endpoint: 'https://my.s3.endpoint',
}),
},
});
await egressClient.startRoomCompositeEgress('my-room', {file: fileOutput});

Google Cloud Storage

For Egress to upload to Google Cloud Storage, you'll need to provide credentials in JSON.

This can be obtained by first creating a service account that has permissions to create storage objects (i.e. Storage Object Creator). Then create a key for that account and export as a JSON file. We'll refer to this file as credentials.json.

import * as fs from 'fs';
const content = fs.readFileSync('/path/to/credentials.json')
const fileOutput = new EncodedFileOutput({
fileType: EncodedFileType.MP4,
filepath: 'livekit-demo/room-composite-test.mp4',
output: {
case: 'gcp',
value: new GCPUpload({
// credentials need to be a JSON encoded string containing credentials
credentials: content.toString(),
bucket: 'my-bucket'
}),
},
});
await egressClient.startRoomCompositeEgress('my-room', {file: fileOutput});

Azure

In order to upload to Azure Blob Storage, you'll need the account's shared access key.

const fileOutput = new EncodedFileOutput({
fileType: EncodedFileType.MP4,
filepath: 'livekit-demo/room-composite-test.mp4',
output: {
case: 'azure',
value: new AzureBlobUpload({
accountName: 'my-account',
accountKey: 'shared-access-key',
containerName: 'my-container',
}),
},
});
await egressClient.startRoomCompositeEgress('my-room', {file: fileOutput});

Service Architecture

Depending on your request type, the egress service will either launch a web template in Chrome and connect to the room (room composite requests), or it will use the sdk directly (track and track composite requests). It uses GStreamer to encode, and can output to a file or to one or more streams.

Egress instance

API

All RPC definitions and options can be found here.

The Egress API exists within our server SDKs and CLI

You can also use curl to interact with Egress APIs. To do so, you can POST to:

https://<your-livekit-host>/twirp/livekit.Egress/<MethodName>

Requests to Egress service need roomRecord permission in the access token.

For example:

% curl -X POST https://<your-livekit-host>/twirp/livekit.Egress/StartRoomCompositeEgress \
-H "Authorization: Bearer <access-token>" \
-H 'Content-Type: application/json' \
-d '{"room_name": "your-room", "segments": {"filename_prefix": "your-hls-playlist.m3u8", "s3": {"access_key": "<key>", "secret": "<secret>", "bucket": "<bucket>", "region": "<bucket-region>"}}}'
{"egress_id":"EG_MU4QwhXUhWf9","room_id":"<room-id>","room_name":"your-room","status":"EGRESS_STARTING"...}

StartRoomCompositeEgress

Starts a new Composite Recording using a web browser as the rendering engine.

ParameterTypeRequiredDescription
room_namestringyesname of room to record
layoutstringlayout parameter that is passed to the template
audio_onlybooltrue if resulting output should only contain audio
video_onlybooltrue if resulting output should only contain video
custom_base_urlstringURL to the page that would composite tracks, uses embedded templates if left blank
file_outputsEncodedFileOutput[]output to MP4 file. currently only supports a single entry
segment_outputsSegmentedFileOutput[]output to HLS segments. currently only supports a single entry
stream_outputsStreamOutput[]output to a stream. currently only supports a single entry, though it could includ multiple destination URLs
image_outputsImageOutput[]output to a succession of snapshot images taken at a given interval (thumbnails). Currently only supports a single entry.
presetEncodingOptionsPresetencoding preset to use. only one of preset or advanced could be set
advancedEncodingOptionsadvanced encoding options. only one of preset or advanced could be set

StartTrackCompositeEgress

Starts a new Track Composite

ParameterTypeRequiredDescription
room_namestringyesname of room to record
audio_track_idstringID of audio track to composite
video_track_idstringID of video track to composite
file_outputsEncodedFileOutput[]output to MP4 file. currently only supports a single entry
segment_outputsSegmentedFileOutput[]output to HLS segments. currently only supports a single entry
stream_outputsStreamOutput[]output to a stream. currently only supports a single entry, though it could includ multiple destination URLs
image_outputsImageOutput[]output to a succession of snapshot images taken at a given interval (thumbnails). Currently only supports a single entry.
presetEncodingOptionsPresetencoding preset to use. only one of preset or advanced could be set
advancedEncodingOptionsadvanced encoding options. only one of preset or advanced could be set

StartTrackEgress

Starts a new Track Egress

ParameterTypeRequiredDescription
room_namestringyesname of room to record
track_idstringlayout parameter that is passed to the template
fileDirectFileOutputonly one of file or websocket_url can be set
websocket_urlstringurl to websocket to receive audio output. only one of file or websocket_url can be set

StartWebEgress

Starts a new Web Egress

ParameterTypeRequiredDescription
urlstringyesURL of the web page to record
audio_onlybooltrue if resulting output should only contain audio
video_onlybooltrue if resulting output should only contain video
file_outputsEncodedFileOutput[]output to MP4 file. currently only supports a single entry
segment_outputsSegmentedFileOutput[]output to HLS segments. currently only supports a single entry
stream_outputsStreamOutput[]output to a stream. currently only supports a single entry, though it could includ multiple destination URLs
image_outputsImageOutput[]output to a succession of snapshot images taken at a given interval (thumbnails). Currently only supports a single entry.
presetEncodingOptionsPresetencoding preset to use. only one of preset or advanced could be set
advancedEncodingOptionsadvanced encoding options. only one of preset or advanced could be set

UpdateLayout

Used to change the web layout on an active RoomCompositeEgress.

ParameterTypeRequiredDescription
egress_idstringyesEgress ID to update
layoutstringyeslayout to update to
const info = await egressClient.updateLayout(egressID, 'grid-light');

UpdateStream

Used to add or remove stream urls from an active stream

Note: you can only add outputs to an Egress that was started with stream_outputs set.

ParameterTypeRequiredDescription
egress_idstringyesEgress ID to update
add_output_urlsstring[]URLs to add to the egress as output destinations
remove_output_urlsstring[]URLs to remove from the egress
const streamOutput = new StreamOutput({
protocol: StreamProtocol.RTMP,
urls: ['rtmp://live.twitch.tv/app/<stream-key>']
});
var info = await egressClient.startRoomCompositeEgress('my-room', {stream: streamOutput});
const streamEgressID = info.egressId;
info = await egressClient.updateStream(
streamEgressID,
['rtmp://a.rtmp.youtube.com/live2/stream-key']
);

ListEgress

Used to list active egress. Does not include completed egress.

const res = await egressClient.listEgress();

StopEgress

Stops an active egress.

const info = await egressClient.stopEgress(egressID);

Types

EncodedFileOutput

FieldTypeDescription
filepathstringdefault {room_name}-{time}
disable_manifestboolby default, Egress outputs a {filepath}.json with metadata of the file
s3S3Uploadset if uploading to S3 compatible storage. only one storage output can be set
gcpGCPUploadset if uploading to GCP
azureAzureBlobUploadset if uploading to Azure
aliOSSAliOSSUploadset if uploading to AliOSS

DirectFileOutput

FieldTypeDescription
filepathstringdefault {track_id}-{time}
disable_manifestboolby default, Egress outputs a {filepath}.json with metadata of the file
s3S3Uploadset if uploading to S3 compatible storage. only one storage output can be set
gcpGCPUploadset if uploading to GCP
azureAzureBlobUploadset if uploading to Azure
aliOSSAliOSSUploadset if uploading to AliOSS

SegmentedFileOutput

FieldTypeDescription
filename_prefixstringprefix used in each segment (include any paths here)
playlist_namestringname of the m3u8 playlist. when empty, matches filename_prefix
segment_durationuint32length of each segment (defaults to 4s)
filename_suffixSegmentedFileSuffixINDEX (1, 2, 3) or TIMESTAMP (in UTC)
disable_manifestbool
s3S3Uploadset if uploading to S3 compatible storage. only one storage output can be set
gcpGCPUploadset if uploading to GCP
azureAzureBlobUploadset if uploading to Azure
aliOSSAliOSSUploadset if uploading to AliOSS

StreamOutput

FieldTypeDescription
protocolSreamProtocol(optional) only RTMP is supported
urlsstring[]list of URLs to send stream to

ImageOutput

FieldTypeDescription
capture_intervaluint32time in seconds between each snapshot
widthint32width of the snapshot images (optional, the original width will be used if not provided)
heightint32height of the snapshot images (optional, the original width will be used if not provided)
filename_prefixstringprefix used in each image filename (include any paths here)
filename_suffixImageFileSuffixINDEX (1, 2, 3) or TIMESTAMP (in UTC)
image_codecImageCodecIC_DEFAULT or IC_JPEG (optional, both options will cause JPEGs to be generated currently)
disable_manifestboolby default, Egress outputs a {filepath}.json with a list of exported snapshots
s3S3Uploadset if uploading to S3 compatible storage. only one storage output can be set
gcpGCPUploadset if uploading to GCP
azureAzureBlobUploadset if uploading to Azure
aliOSSAliOSSUploadset if uploading to AliOSS

S3Upload

FieldTypeDescription
access_keystring
secretstringS3 secret key
bucketstringdestination bucket
regionstringregion of the S3 bucket (optional)
endpointstringURL to use for S3 (optional)
force_path_styleboolleave bucket in the path and never to sub-domain (optional)
metadatamap<string, string>metadata key/value pairs to store (optional)
taggingstring(optional)
proxyProxyConfigProxy server to use when uploading(optional)

GCPUpload

FieldTypeDescription
credentialsstringContents of credentials.json
bucketstringdestination bucket
proxyProxyConfigProxy server to use when uploading(optional)

AzureBlobUpload

FieldTypeDescription
account_namestring
account_keystring
container_namestringdestination container

AliOSSUpload

FieldTypeDescription
access_keystring
secretstring
bucketstring
regionstring
endpointstring

EncodingOptions

FieldTypeDescription
widthint32
heightint32
depthint32default 24
framerateint32default 30
audio_codecAudioCodecdefault AAC
audio_bitrateint32128
audio_frequencyint3244100
video_codecVideoCodecdefault H264_MAIN
video_bitrateint32default 4500
key_frame_intervalint32default 4s

EncodingOptionsPreset

Enum, valid values:

  • H264_720P_30: 0
  • H264_720P_60: 1
  • H264_1080P_30: 2
  • H264_1080P_60: 3
  • PORTRAIT_H264_720P_30: 4
  • PORTRAIT_H264_720P_60: 5
  • PORTRAIT_H264_1080P_30: 6
  • PORTRAIT_H264_1080P_60: 7

ProxyConfig

For S3 and GCP, you can specify a proxy server for Egress to use when uploading files.

This can be helpful to avoid network restrictions on the destination buckets.

FieldTypeDescription
urlstringURL of the proxy
usernamestringusername for basic auth (optional)
passwordstringpassword for basic auth (optional)

Deployment

See the deployment docs for more info on deployment, config, and autoscaling.