1syntax = "proto3";
2
3package livekit;
4option go_package = "github.com/livekit/protocol/livekit";
5option csharp_namespace = "LiveKit.Proto";
6option ruby_package = "LiveKit::Proto";
7
8import "google/protobuf/timestamp.proto";
9import "livekit_egress.proto";
10
11message Room {
12 string sid = 1;
13 string name = 2;
14 uint32 empty_timeout = 3;
15 uint32 max_participants = 4;
16 int64 creation_time = 5;
17 string turn_password = 6;
18 repeated Codec enabled_codecs = 7;
19 string metadata = 8;
20 uint32 num_participants = 9;
21 bool active_recording = 10;
22}
23
24// room info that should not be returned to clients
25message RoomInternal {
26 AutoTrackEgress track_egress = 1;
27}
28
29message AutoTrackEgress {
30 string file_prefix = 1;
31 oneof output {
32 S3Upload s3 = 2;
33 GCPUpload gcp = 3;
34 AzureBlobUpload azure = 4;
35 }
36}
37
38message Codec {
39 string mime = 1;
40 string fmtp_line = 2;
41}
42
43message ParticipantPermission {
44 // allow participant to subscribe to other tracks in the room
45 bool can_subscribe = 1;
46 // allow participant to publish new tracks to room
47 bool can_publish = 2;
48 // allow participant to publish data
49 bool can_publish_data = 3;
50 // indicates that it's hidden to others
51 bool hidden = 7;
52 // indicates it's a recorder instance
53 bool recorder = 8;
54}
55
56message ParticipantInfo {
57 enum State {
58 // websocket' connected, but not offered yet
59 JOINING = 0;
60 // server received client offer
61 JOINED = 1;
62 // ICE connectivity established
63 ACTIVE = 2;
64 // WS disconnected
65 DISCONNECTED = 3;
66 }
67 string sid = 1;
68 string identity = 2;
69 State state = 3;
70 repeated TrackInfo tracks = 4;
71 string metadata = 5;
72 // timestamp when participant joined room, in seconds
73 int64 joined_at = 6;
74 string name = 9;
75 uint32 version = 10;
76 ParticipantPermission permission = 11;
77 string region = 12;
78 // indicates the participant has an active publisher connection
79 // and can publish to the server
80 bool is_publisher = 13;
81}
82
83enum TrackType {
84 AUDIO = 0;
85 VIDEO = 1;
86 DATA = 2;
87}
88
89enum TrackSource {
90 UNKNOWN = 0;
91 CAMERA = 1;
92 MICROPHONE = 2;
93 SCREEN_SHARE = 3;
94 SCREEN_SHARE_AUDIO = 4;
95}
96
97message SimulcastCodecInfo {
98 string mime_type = 1;
99 string mid = 2;
100 string cid = 3;
101 repeated VideoLayer layers = 4;
102}
103
104message TrackInfo {
105 string sid = 1;
106 TrackType type = 2;
107 string name = 3;
108 bool muted = 4;
109 // original width of video (unset for audio)
110 // clients may receive a lower resolution version with simulcast
111 uint32 width = 5;
112 // original height of video (unset for audio)
113 uint32 height = 6;
114 // true if track is simulcasted
115 bool simulcast = 7;
116 // true if DTX (Discontinuous Transmission) is disabled for audio
117 bool disable_dtx = 8;
118 // source of media
119 TrackSource source = 9;
120 repeated VideoLayer layers = 10;
121 // mime type of codec
122 string mime_type = 11;
123 string mid = 12;
124 repeated SimulcastCodecInfo codecs = 13;
125}
126
127enum VideoQuality {
128 LOW = 0;
129 MEDIUM = 1;
130 HIGH = 2;
131 OFF = 3;
132}
133
134// provide information about available spatial layers
135message VideoLayer {
136 // for tracks with a single layer, this should be HIGH
137 VideoQuality quality = 1;
138 uint32 width = 2;
139 uint32 height = 3;
140 // target bitrate, server will measure actual
141 uint32 bitrate = 4;
142 uint32 ssrc = 5;
143}
144
145// new DataPacket API
146message DataPacket {
147 enum Kind {
148 RELIABLE = 0;
149 LOSSY = 1;
150 }
151 Kind kind = 1;
152 oneof value {
153 UserPacket user = 2;
154 ActiveSpeakerUpdate speaker = 3;
155 }
156}
157
158message ActiveSpeakerUpdate {
159 repeated SpeakerInfo speakers = 1;
160}
161
162message SpeakerInfo {
163 string sid = 1;
164 // audio level, 0-1.0, 1 is loudest
165 float level = 2;
166 // true if speaker is currently active
167 bool active = 3;
168}
169
170message UserPacket {
171 // participant ID of user that sent the message
172 string participant_sid = 1;
173 // user defined payload
174 bytes payload = 2;
175 // the ID of the participants who will receive the message (the message will be sent to all the people in the room if this variable is empty)
176 repeated string destination_sids = 3;
177}
178
179enum ConnectionQuality {
180 POOR = 0;
181 GOOD = 1;
182 EXCELLENT = 2;
183}
184
185message ParticipantTracks {
186 // participant ID of participant to whom the tracks belong
187 string participant_sid = 1;
188 repeated string track_sids = 2;
189}
190
191// details about the server
192message ServerInfo {
193 enum Edition {
194 Standard = 0;
195 Cloud = 1;
196 }
197 Edition edition = 1;
198 string version = 2;
199 int32 protocol = 3;
200 string region = 4;
201 string node_id = 5;
202 // additional debugging information. sent only if server is in development mode
203 string debug_info = 6;
204}
205
206// details about the client
207message ClientInfo {
208 enum SDK {
209 UNKNOWN = 0;
210 JS = 1;
211 SWIFT = 2;
212 ANDROID = 3;
213 FLUTTER = 4;
214 GO = 5;
215 UNITY = 6;
216 }
217
218 SDK sdk = 1;
219 string version = 2;
220 int32 protocol = 3;
221 string os = 4;
222 string os_version = 5;
223 string device_model = 6;
224 string browser = 7;
225 string browser_version = 8;
226 string address = 9;
227 // wifi, wired, cellular, vpn, empty if not known
228 string network = 10;
229}
230
231// server provided client configuration
232message ClientConfiguration {
233 VideoConfiguration video = 1;
234 VideoConfiguration screen = 2;
235
236 ClientConfigSetting resume_connection = 3;
237 DisabledCodecs disabled_codecs = 4;
238 ClientConfigSetting force_relay = 5;
239}
240
241enum ClientConfigSetting {
242 UNSET = 0;
243 DISABLED = 1;
244 ENABLED = 2;
245}
246
247message VideoConfiguration {
248 ClientConfigSetting hardware_encoder = 1;
249}
250
251message DisabledCodecs {
252 repeated Codec codecs = 1;
253}
254
255enum DisconnectReason {
256 UNKNOWN_REASON = 0;
257 CLIENT_INITIATED = 1;
258 DUPLICATE_IDENTITY = 2;
259 SERVER_SHUTDOWN = 3;
260 PARTICIPANT_REMOVED = 4;
261 ROOM_DELETED = 5;
262 STATE_MISMATCH = 6;
263 JOIN_FAILURE = 7;
264}
265
266message RTPStats {
267 google.protobuf.Timestamp start_time = 1;
268 google.protobuf.Timestamp end_time = 2;
269 double duration = 3;
270
271 uint32 packets = 4;
272 double packet_rate = 5;
273
274 uint64 bytes = 6;
275 uint64 header_bytes = 39;
276 double bitrate = 7;
277
278 uint32 packets_lost = 8;
279 double packet_loss_rate = 9;
280 float packet_loss_percentage = 10;
281
282 uint32 packets_duplicate = 11;
283 double packet_duplicate_rate = 12;
284
285 uint64 bytes_duplicate = 13;
286 uint64 header_bytes_duplicate = 40;
287 double bitrate_duplicate = 14;
288
289 uint32 packets_padding = 15;
290 double packet_padding_rate = 16;
291
292 uint64 bytes_padding = 17;
293 uint64 header_bytes_padding = 41;
294 double bitrate_padding = 18;
295
296 uint32 packets_out_of_order = 19;
297
298 uint32 frames = 20;
299 double frame_rate = 21;
300
301 double jitter_current = 22;
302 double jitter_max = 23;
303
304 map<int32, uint32> gap_histogram = 24;
305
306 uint32 nacks = 25;
307 uint32 nack_acks = 37;
308 uint32 nack_misses = 26;
309 uint32 nack_repeated = 38;
310
311 uint32 plis = 27;
312 google.protobuf.Timestamp last_pli = 28;
313
314 uint32 firs = 29;
315 google.protobuf.Timestamp last_fir = 30;
316
317 uint32 rtt_current = 31;
318 uint32 rtt_max = 32;
319
320 uint32 key_frames = 33;
321 google.protobuf.Timestamp last_key_frame = 34;
322
323 uint32 layer_lock_plis = 35;
324 google.protobuf.Timestamp last_layer_lock_pli = 36;
325}
326
327message TimedVersion {
328 int64 unix_micro = 1;
329 int32 ticks = 2;
330}