LiveKit C++ SDK
Real-time audio/video SDK for C++
Loading...
Searching...
No Matches
room.h
1/*
2 * Copyright 2025 LiveKit
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an “AS IS” BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef LIVEKIT_ROOM_H
18#define LIVEKIT_ROOM_H
19
20#include "livekit/data_stream.h"
21#include "livekit/e2ee.h"
22#include "livekit/ffi_handle.h"
23#include "livekit/room_event_types.h"
24#include "livekit/subscription_thread_dispatcher.h"
25
26#include <cstdint>
27#include <memory>
28#include <mutex>
29
30namespace livekit {
31
32class RoomDelegate;
33struct RoomInfoData;
34namespace proto {
35class FfiEvent;
36}
37
38struct E2EEOptions;
39class E2EEManager;
40class LocalParticipant;
41class RemoteParticipant;
42
43// Represents a single ICE server configuration.
44struct IceServer {
45 // TURN/STUN server URL (e.g. "stun:stun.l.google.com:19302").
46 std::string url;
47
48 // Optional username for TURN authentication.
49 std::string username;
50
51 // Optional credential (password) for TURN authentication.
52 std::string credential;
53};
54
55// WebRTC configuration (ICE, transport, etc.).
56struct RtcConfig {
57 // ICE transport type (e.g., ALL, RELAY). Maps to proto::IceTransportType.
58 int ice_transport_type = 0;
59
60 // Continuous or single ICE gathering. Maps to
61 // proto::ContinualGatheringPolicy.
62 int continual_gathering_policy = 0;
63
64 // List of STUN/TURN servers for ICE candidate generation.
65 std::vector<IceServer> ice_servers;
66};
67
68// Top-level room connection options.
70 // If true (default), automatically subscribe to all remote tracks.
71 // This is CRITICAL. Without auto_subscribe, you will never receive:
72 // - `track_subscribed` events
73 // - remote audio/video frames
74 bool auto_subscribe = true;
75
76 // Enable dynacast (server sends optimal layers depending on subscribers).
77 bool dynacast = false;
78
79 // Enable single peer connection mode. When true, uses one RTCPeerConnection
80 // for both publishing and subscribing instead of two separate connections.
81 // Falls back to dual peer connection if the server doesn't support single PC.
82 bool single_peer_connection = false;
83
84 // Optional WebRTC configuration (ICE policy, servers, etc.)
85 std::optional<RtcConfig> rtc_config;
86
87 // Optional end-to-end encryption settings.
88 std::optional<E2EEOptions> encryption;
89};
90
97class Room {
98public:
99 Room();
100 ~Room();
101
102 /* Assign a RoomDelegate that receives room lifecycle callbacks.
103 *
104 * The delegate must remain valid for the lifetime of the Room or until a
105 * different delegate is assigned. The Room does not take ownership.
106 * Typical usage:
107 * class MyDelegate : public RoomDelegate { ... };
108 * MyDelegate del;
109 * Room room;
110 * room.setDelegate(&del);
111 */
112 void setDelegate(RoomDelegate *delegate);
113
114 /* Connect to a LiveKit room using the given URL and token, applying the
115 * supplied connection options.
116 *
117 * Parameters:
118 * url — WebSocket URL of the LiveKit server.
119 * token — Access token for authentication.
120 * options — Connection options controlling auto-subscribe,
121 * dynacast, E2EE, and WebRTC configuration.
122 * Behavior:
123 * - Registers an FFI event listener *before* sending the connect request.
124 * - Sends a proto::FfiRequest::Connect with the URL, token,
125 * and the provided RoomOptions.
126 * - Blocks until the FFI connect response arrives.
127 * - Initializes local participant and remote participants.
128 * - Emits room/participant/track events to the delegate.
129 * IMPORTANT:
130 * RoomOptions defaults auto_subscribe = true.
131 * Without auto_subscribe enabled, remote tracks will NOT be subscribed
132 * automatically, and no remote audio/video will ever arrive.
133 */
134 bool Connect(const std::string &url, const std::string &token,
135 const RoomOptions &options);
136
137 // Accessors
138
139 /* Retrieve static metadata about the room.
140 * This contains fields such as:
141 * - SID
142 * - room name
143 * - metadata
144 * - participant counts
145 * - creation timestamp
146 */
147 RoomInfoData room_info() const;
148
149 /* Get the local participant.
150 *
151 * This object represents the current user, including:
152 * - published tracks (audio/video/screen)
153 * - identity, SID, metadata
154 * - publishing/unpublishing operations
155 * Return value:
156 * Non-null pointer after successful Connect().
157 */
158 LocalParticipant *localParticipant() const;
159
160 /* Look up a remote participant by identity.
161 *
162 * Parameters:
163 * identity — The participant’s identity string (not SID)
164 * Return value:
165 * Pointer to RemoteParticipant if present, otherwise nullptr.
166 * RemoteParticipant contains:
167 * - identity/name/metadata
168 * - track publications
169 * - callbacks for track subscribed/unsubscribed, muted/unmuted
170 */
171 RemoteParticipant *remoteParticipant(const std::string &identity) const;
172
174 std::vector<std::shared_ptr<RemoteParticipant>> remoteParticipants() const;
175
176 /* Register a handler for incoming text streams on a specific topic.
177 *
178 * When a remote participant opens a text stream with the given topic,
179 * the handler is invoked with:
180 * - a shared_ptr<TextStreamReader> for consuming the stream
181 * - the identity of the participant who sent the stream
182 *
183 * Notes:
184 * - Only one handler may be registered per topic.
185 * - If no handler is registered for a topic, incoming streams with that
186 * topic are ignored.
187 * - The handler is invoked on the Room event thread. The handler must
188 * not block; spawn a background thread if synchronous reading is
189 * required.
190 *
191 * Throws:
192 * std::runtime_error if a handler is already registered for the topic.
193 */
194 void registerTextStreamHandler(const std::string &topic,
195 TextStreamHandler handler);
196
197 /* Unregister the text stream handler for the given topic.
198 *
199 * If no handler exists for the topic, this function is a no-op.
200 */
201 void unregisterTextStreamHandler(const std::string &topic);
202
203 /* Register a handler for incoming byte streams on a specific topic.
204 *
205 * When a remote participant opens a byte stream with the given topic,
206 * the handler is invoked with:
207 * - a shared_ptr<ByteStreamReader> for consuming the stream
208 * - the identity of the participant who sent the stream
209 *
210 * Notes:
211 * - Only one handler may be registered per topic.
212 * - If no handler is registered for a topic, incoming streams with that
213 * topic are ignored.
214 * - The ByteStreamReader remains valid as long as the shared_ptr is held,
215 * preventing lifetime-related crashes when reading asynchronously.
216 *
217 * Throws:
218 * std::runtime_error if a handler is already registered for the topic.
219 */
220 void registerByteStreamHandler(const std::string &topic,
221 ByteStreamHandler handler);
222
223 /* Unregister the byte stream handler for the given topic.
224 *
225 * If no handler exists for the topic, this function is a no-op.
226 */
227 void unregisterByteStreamHandler(const std::string &topic);
228
238
239 // ---------------------------------------------------------------
240 // Frame callbacks
241 // ---------------------------------------------------------------
242
246 void setOnAudioFrameCallback(const std::string &participant_identity,
247 TrackSource source, AudioFrameCallback callback,
248 AudioStream::Options opts = {});
249
253 void setOnAudioFrameCallback(const std::string &participant_identity,
254 const std::string &track_name,
255 AudioFrameCallback callback,
256 AudioStream::Options opts = {});
257
261 void setOnVideoFrameCallback(const std::string &participant_identity,
262 TrackSource source, VideoFrameCallback callback,
263 VideoStream::Options opts = {});
264
268 void setOnVideoFrameCallback(const std::string &participant_identity,
269 const std::string &track_name,
270 VideoFrameCallback callback,
271 VideoStream::Options opts = {});
272
276 void clearOnAudioFrameCallback(const std::string &participant_identity,
277 TrackSource source);
281 void clearOnAudioFrameCallback(const std::string &participant_identity,
282 const std::string &track_name);
283
287 void clearOnVideoFrameCallback(const std::string &participant_identity,
288 TrackSource source);
289
293 void clearOnVideoFrameCallback(const std::string &participant_identity,
294 const std::string &track_name);
295
299 DataFrameCallbackId
300 addOnDataFrameCallback(const std::string &participant_identity,
301 const std::string &track_name,
302 DataFrameCallback callback);
303
307 void removeOnDataFrameCallback(DataFrameCallbackId id);
308
309private:
310 friend class RoomCallbackTest;
311
312 mutable std::mutex lock_;
313 ConnectionState connection_state_ = ConnectionState::Disconnected;
314 RoomDelegate *delegate_ = nullptr; // Not owned
315 RoomInfoData room_info_;
316 std::shared_ptr<FfiHandle> room_handle_;
317 std::unique_ptr<LocalParticipant> local_participant_;
318 std::unordered_map<std::string, std::shared_ptr<RemoteParticipant>>
319 remote_participants_;
320 // Data stream
321 std::unordered_map<std::string, TextStreamHandler> text_stream_handlers_;
322 std::unordered_map<std::string, ByteStreamHandler> byte_stream_handlers_;
323 std::unordered_map<std::string, std::shared_ptr<TextStreamReader>>
324 text_stream_readers_;
325 std::unordered_map<std::string, std::shared_ptr<ByteStreamReader>>
326 byte_stream_readers_;
327 // E2EE
328 std::unique_ptr<E2EEManager> e2ee_manager_;
329 std::shared_ptr<SubscriptionThreadDispatcher> subscription_thread_dispatcher_;
330
331 // FfiClient listener ID (0 means no listener registered)
332 int listener_id_{0};
333
334 void OnEvent(const proto::FfiEvent &event);
335};
336} // namespace livekit
337
338#endif /* LIVEKIT_ROOM_H */
Definition e2ee.h:109
Definition local_participant.h:57
Definition remote_participant.h:29
Definition room_delegate.h:34
Definition room.h:97
void setOnAudioFrameCallback(const std::string &participant_identity, TrackSource source, AudioFrameCallback callback, AudioStream::Options opts={})
Sets the audio frame callback via SubscriptionThreadDispatcher.
void setOnVideoFrameCallback(const std::string &participant_identity, TrackSource source, VideoFrameCallback callback, VideoStream::Options opts={})
Sets the video frame callback via SubscriptionThreadDispatcher.
void clearOnAudioFrameCallback(const std::string &participant_identity, TrackSource source)
Clears the audio frame callback via SubscriptionThreadDispatcher.
void clearOnVideoFrameCallback(const std::string &participant_identity, TrackSource source)
Clears the video frame callback via SubscriptionThreadDispatcher.
void removeOnDataFrameCallback(DataFrameCallbackId id)
Removes the data frame callback via SubscriptionThreadDispatcher.
void setOnAudioFrameCallback(const std::string &participant_identity, const std::string &track_name, AudioFrameCallback callback, AudioStream::Options opts={})
Sets the audio frame callback via SubscriptionThreadDispatcher.
std::vector< std::shared_ptr< RemoteParticipant > > remoteParticipants() const
Returns a snapshot of all current remote participants.
void clearOnVideoFrameCallback(const std::string &participant_identity, const std::string &track_name)
Clears the video frame callback via SubscriptionThreadDispatcher.
DataFrameCallbackId addOnDataFrameCallback(const std::string &participant_identity, const std::string &track_name, DataFrameCallback callback)
Adds a data frame callback via SubscriptionThreadDispatcher.
void clearOnAudioFrameCallback(const std::string &participant_identity, const std::string &track_name)
Clears the audio frame callback via SubscriptionThreadDispatcher.
void setOnVideoFrameCallback(const std::string &participant_identity, const std::string &track_name, VideoFrameCallback callback, VideoStream::Options opts={})
Sets the video frame callback via SubscriptionThreadDispatcher.
E2EEManager * e2eeManager() const
Configuration options for AudioStream creation.
Definition audio_stream.h:67
Definition room.h:44
Definition room_event_types.h:141
Definition room.h:69
Definition room.h:56
Definition video_stream.h:62