Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ jobs:
libssl-dev \
libprotobuf-dev protobuf-compiler \
libabsl-dev \
libcurl4-openssl-dev \
libwayland-dev libdecor-0-dev

- name: Install deps (macOS)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cpp-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
sudo apt-get install -y \
build-essential cmake ninja-build pkg-config \
llvm-dev libclang-dev clang \
libssl-dev wget ca-certificates gnupg
libssl-dev libcurl4-openssl-dev wget ca-certificates gnupg

- name: Install clang-tidy 19 (for ExcludeHeaderFilterRegex support)
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/make-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ jobs:
libssl-dev \
libprotobuf-dev protobuf-compiler \
libabsl-dev \
libcurl4-openssl-dev \
libwayland-dev libdecor-0-dev

- name: Install deps (macOS)
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ jobs:
libssl-dev \
libprotobuf-dev protobuf-compiler \
libabsl-dev \
libcurl4-openssl-dev \
libwayland-dev libdecor-0-dev \
jq

Expand Down Expand Up @@ -309,6 +310,7 @@ jobs:
libssl-dev \
libprotobuf-dev protobuf-compiler \
libabsl-dev \
libcurl4-openssl-dev \
libwayland-dev libdecor-0-dev
pip install --break-system-packages gcovr

Expand Down
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@ add_library(livekit SHARED
src/room_proto_converter.cpp
src/room_proto_converter.h
src/subscription_thread_dispatcher.cpp
src/token_source.cpp
src/token_source_http.cpp
src/token_source_json.cpp
src/token_source_jwt.cpp
src/token_source_internal.h
src/local_participant.cpp
src/remote_participant.cpp
src/stats.cpp
Expand Down Expand Up @@ -461,6 +466,13 @@ target_link_libraries(livekit
${LIVEKIT_PROTOBUF_TARGET}
)

if(WIN32)
target_link_libraries(livekit PRIVATE winhttp)
else()
find_package(CURL REQUIRED)
target_link_libraries(livekit PRIVATE CURL::libcurl)
endif()

target_compile_definitions(livekit
PRIVATE
SPDLOG_ACTIVE_LEVEL=${_SPDLOG_ACTIVE_LEVEL}
Expand Down
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,60 @@ room->addOnDataFrameCallback(sender_identity, "app-data",

For end-to-end samples and a fuller set of demos, see the [cpp-example-collection repo](https://github.com/livekit-examples/cpp-example-collection).

### Token source (dynamic tokens)

The SDK provides token sources for literal credentials, custom async logic,
HTTP token-server endpoints, LiveKit Cloud sandbox (dev), and JWT-aware caching.
See the [token server docs](https://docs.livekit.io/frontends/build/authentication/).

**Literal** — static URL + JWT:

```cpp
#include <livekit/token_source.h>

livekit::ConnectionDetails details;
details.server_url = url;
details.participant_token = jwt;

auto source = livekit::LiteralTokenSource::fromDetails(std::move(details));
if (!room->connect(*source, options)) {
std::cerr << "Failed to connect to LiveKit\n";
return 1;
}
```

**Endpoint** — POST to your token server:

```cpp
livekit::TokenRequestOptions request;
request.room_name = "my-room";
request.participant_identity = "user-123";

auto source = livekit::EndpointTokenSource::fromUrl("https://your-backend.example.com/token");
if (!room->connect(*source, request, options)) {
return 1;
}
```

**Custom** — wrap your own fetch logic:

```cpp
auto source = livekit::CustomTokenSource::fromCallback([](const livekit::TokenRequestOptions& options) {
std::promise<livekit::Result<livekit::ConnectionDetails, livekit::TokenSourceError>> promise;
// fetch from your backend, then:
promise.set_value(livekit::Result<livekit::ConnectionDetails, livekit::TokenSourceError>::success(details));
return promise.get_future();
});
```

During an active session the SDK refreshes tokens internally for reconnect.
`Room::participantToken()` returns the latest JWT and
`RoomDelegate::onTokenRefreshed` fires when it changes.

## Features

- Connect to LiveKit rooms (Cloud or self-hosted)
- Dynamic token sourcing (literal, custom, endpoint, sandbox, caching)
- Receive remote audio/video tracks
- Publish local audio/video tracks
- Data tracks (low-level) and data streams (high-level)
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libasound2-dev \
libabsl-dev \
libclang-dev \
libcurl4-openssl-dev \
libdrm-dev \
libglib2.0-dev \
libprotobuf-dev \
Expand Down
1 change: 1 addition & 0 deletions include/livekit/livekit.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "livekit/room.h"
#include "livekit/room_delegate.h"
#include "livekit/room_event_types.h"
#include "livekit/token_source.h"
#include "livekit/tracing.h"
#include "livekit/track_publication.h"
#include "livekit/video_frame.h"
Expand Down
24 changes: 24 additions & 0 deletions include/livekit/room.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <chrono>
#include <cstdint>
#include <functional>
#include <future>
#include <memory>
#include <mutex>
Expand All @@ -28,6 +29,7 @@
#include "livekit/room_event_types.h"
#include "livekit/stats.h"
#include "livekit/subscription_thread_dispatcher.h"
#include "livekit/token_source.h"
#include "livekit/visibility.h"

namespace livekit {
Expand Down Expand Up @@ -165,6 +167,22 @@ class LIVEKIT_API Room {
/// automatically, and no remote audio/video will ever arrive.
bool connect(const std::string& url, const std::string& token, const RoomOptions& options);

/// Connect using a fixed token source that supplies server URL and JWT.
///
/// @param token_source Token source invoked on the application thread.
/// @param options Connection options.
/// @return @c false if fetching credentials fails or connect fails.
bool connect(TokenSourceFixed& token_source, const RoomOptions& options);

/// Connect using a configurable token source.
///
/// @param token_source Token source invoked on the application thread.
/// @param request_options Parameters encoded into the token request.
/// @param options Connection options.
/// @return @c false if fetching credentials fails or connect fails.
bool connect(TokenSourceConfigurable& token_source, const TokenRequestOptions& request_options,
const RoomOptions& options);

/// Disconnect from the room.
///
/// This method attempts a best-effort graceful disconnect of the room. If the room was connected prior, after @ref
Expand Down Expand Up @@ -230,6 +248,11 @@ class LIVEKIT_API Room {
/// Returns the current connection state of the room.
ConnectionState connectionState() const;

/// Returns the participant JWT from the last successful connect or token refresh.
///
/// Empty when the room has never connected or after disconnect.
std::string participantToken() const;

/// Retrieve aggregated WebRTC stats for this room session.
///
/// Dispatches an async request to the server and returns a future that
Expand Down Expand Up @@ -334,6 +357,7 @@ class LIVEKIT_API Room {

mutable std::mutex lock_;
ConnectionState connection_state_ = ConnectionState::Disconnected;
std::string participant_token_;
RoomDelegate* delegate_ = nullptr; // Not owned
RoomInfoData room_info_;
std::shared_ptr<FfiHandle> room_handle_;
Expand Down
3 changes: 3 additions & 0 deletions include/livekit/room_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ class LIVEKIT_API RoomDelegate {
/// Called after the SDK successfully reconnects.
virtual void onReconnected(Room&, const ReconnectedEvent&) {}

/// Called when the server refreshes the session access token.
virtual void onTokenRefreshed(Room&, const TokenRefreshedEvent&) {}

// ------------------------------------------------------------------
// E2EE
// ------------------------------------------------------------------
Expand Down
9 changes: 9 additions & 0 deletions include/livekit/room_event_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,15 @@ struct ReconnectingEvent {};
/// Fired after successfully reconnecting.
struct ReconnectedEvent {};

/// Fired when the server refreshes the session access token.
///
/// The SDK applies the refreshed token internally for reconnect; this event is
/// informational so applications can log or cache the latest token.
struct TokenRefreshedEvent {
/// Refreshed access token.
std::string token;
};

/// Fired when the room has reached end-of-stream (no more events).
struct RoomEosEvent {};

Expand Down
Loading
Loading