syntax = "proto3"; package livekit; option go_package = "github.com/livekit/protocol/livekit"; option csharp_namespace = "LiveKit.Proto"; option ruby_package = "LiveKit::Proto"; service Egress { // start recording or streaming a room, participant, or tracks rpc StartRoomCompositeEgress(RoomCompositeEgressRequest) returns (EgressInfo); rpc StartTrackCompositeEgress(TrackCompositeEgressRequest) returns (EgressInfo); rpc StartTrackEgress(TrackEgressRequest) returns (EgressInfo); // update web composite layout rpc UpdateLayout(UpdateLayoutRequest) returns (EgressInfo); // add or remove stream endpoints rpc UpdateStream(UpdateStreamRequest) returns (EgressInfo); // list available egress rpc ListEgress(ListEgressRequest) returns (ListEgressResponse); // stop a recording or stream rpc StopEgress(StopEgressRequest) returns (EgressInfo); } // composite using a web browser message RoomCompositeEgressRequest { string room_name = 1; // required string layout = 2; // (optional) bool audio_only = 3; // (default false) bool video_only = 4; // (default false) string custom_base_url = 5; // (default https://recorder.livekit.io) oneof output { // required EncodedFileOutput file = 6; StreamOutput stream = 7; SegmentedFileOutput segments = 10; } oneof options { EncodingOptionsPreset preset = 8; // (default H264_720P_30) EncodingOptions advanced = 9; // (optional) } } // containerize up to one audio and one video track message TrackCompositeEgressRequest { string room_name = 1; // required string audio_track_id = 2; // (optional) string video_track_id = 3; // (optional) oneof output { // required EncodedFileOutput file = 4; StreamOutput stream = 5; SegmentedFileOutput segments = 8; } oneof options { EncodingOptionsPreset preset = 6; // (default H264_720P_30) EncodingOptions advanced = 7; // (optional) } } // record tracks individually, without transcoding message TrackEgressRequest { string room_name = 1; // required string track_id = 2; // required oneof output { // required DirectFileOutput file = 3; string websocket_url = 4; } } enum EncodedFileType { DEFAULT_FILETYPE = 0; // file type chosen based on codecs MP4 = 1; OGG = 2; } message EncodedFileOutput { EncodedFileType file_type = 1; // (optional) string filepath = 2; // (optional) oneof output { // required S3Upload s3 = 3; GCPUpload gcp = 4; AzureBlobUpload azure = 5; } } // Used to generate HLS segments or other kind of segmented output message SegmentedFileOutput { SegmentedFileProtocol protocol = 1; // (optional) string filename_prefix = 2; // (optional) string playlist_name = 3; // (optional) uint32 segment_duration = 4; // (optional) oneof output { // required S3Upload s3 = 5; GCPUpload gcp = 6; AzureBlobUpload azure = 7; } } message DirectFileOutput { string filepath = 1; // (optional) oneof output { // required S3Upload s3 = 2; GCPUpload gcp = 3; AzureBlobUpload azure = 4; } } message S3Upload { string access_key = 1; string secret = 2; string region = 3; string endpoint = 4; string bucket = 5; } message GCPUpload { bytes credentials = 1; string bucket = 2; } message AzureBlobUpload { string account_name = 1; string account_key = 2; string container_name = 3; } enum StreamProtocol { DEFAULT_PROTOCOL = 0; // protocol chosen based on urls RTMP = 1; } enum SegmentedFileProtocol { DEFAULT_SEGMENTED_FILE_PROTOCOL = 0; HLS_PROTOCOL = 1; } message StreamOutput { StreamProtocol protocol = 1; // required repeated string urls = 2; // required } enum AudioCodec { DEFAULT_AC = 0; OPUS = 1; AAC = 2; } enum VideoCodec { DEFAULT_VC = 0; H264_BASELINE = 1; H264_MAIN = 2; H264_HIGH = 3; } message EncodingOptions { int32 width = 1; // (default 1920) int32 height = 2; // (default 1080) int32 depth = 3; // (default 24) int32 framerate = 4; // (default 30) AudioCodec audio_codec = 5; // (default OPUS) int32 audio_bitrate = 6; // (default 128) int32 audio_frequency = 7; // (default 44100) VideoCodec video_codec = 8; // (default H264_MAIN) int32 video_bitrate = 9; // (default 4500) } enum EncodingOptionsPreset { H264_720P_30 = 0; // 1280x720, 30fps, 3000kpbs, H.264_MAIN / OPUS H264_720P_60 = 1; // 1280x720, 60fps, 4500kbps, H.264_MAIN / OPUS H264_1080P_30 = 2; // 1920x1080, 30fps, 4500kbps, H.264_MAIN / OPUS H264_1080P_60 = 3; // 1920x1080, 60fps, 6000kbps, H.264_MAIN / OPUS PORTRAIT_H264_720P_30 = 4; // 720x1280, 30fps, 3000kpbs, H.264_MAIN / OPUS PORTRAIT_H264_720P_60 = 5; // 720x1280, 60fps, 4500kbps, H.264_MAIN / OPUS PORTRAIT_H264_1080P_30 = 6; // 1080x1920, 30fps, 4500kbps, H.264_MAIN / OPUS PORTRAIT_H264_1080P_60 = 7; // 1080x1920, 60fps, 6000kbps, H.264_MAIN / OPUS } message UpdateLayoutRequest { string egress_id = 1; string layout = 2; } message UpdateStreamRequest { string egress_id = 1; repeated string add_output_urls = 2; repeated string remove_output_urls = 3; } message ListEgressRequest { string room_name = 1; // (optional, used to filter results) } message ListEgressResponse { repeated EgressInfo items = 1; } message StopEgressRequest { string egress_id = 1; } enum EgressStatus { EGRESS_STARTING = 0; EGRESS_ACTIVE = 1; EGRESS_ENDING = 2; EGRESS_COMPLETE = 3; EGRESS_FAILED = 4; EGRESS_ABORTED = 5; EGRESS_LIMIT_REACHED = 6; } message EgressInfo { string egress_id = 1; string room_id = 2; string room_name = 13; EgressStatus status = 3; int64 started_at = 10; int64 ended_at = 11; string error = 9; oneof request { RoomCompositeEgressRequest room_composite = 4; TrackCompositeEgressRequest track_composite = 5; TrackEgressRequest track = 6; } oneof result { StreamInfoList stream = 7; FileInfo file = 8; SegmentsInfo segments = 12; } } message StreamInfoList { repeated StreamInfo info = 1; } message StreamInfo { enum Status { ACTIVE = 0; FINISHED = 1; FAILED = 2; } string url = 1; int64 started_at = 2; int64 ended_at = 3; int64 duration = 4; Status status = 5; } message FileInfo { string filename = 1; int64 duration = 6; int64 size = 4; string location = 5; } message SegmentsInfo { string playlist_name = 1; int64 duration = 2; int64 size = 3; string playlist_location = 4; int64 segment_count = 5; }