Overview
The C++ SDK connects native desktop, server, robotics, and embedded applications to LiveKit rooms.
Supported platforms
The SDK is built and released for the following platforms:
| Platform | Architecture |
|---|---|
| Windows | x64 |
| Linux | x86_64 and ARM |
| macOS | x86_64 and ARM |
| Nvidia Jetson | ARM |
| Raspberry Pi | ARM |
If no prebuilt release asset matches your platform, LiveKitSDK.cmake fails during CMake configure. In that case, build the SDK from source and use LIVEKIT_LOCAL_SDK_DIR.
Install the C++ SDK
The easiest way to consume the SDK is to use a prebuilt release. The C++ example collection includes a CMake helper that downloads the matching prebuilt SDK archive during CMake configure and makes find_package(LiveKit CONFIG REQUIRED) work. It also lets you point at a local C++ SDK install.
Copy
cmake/LiveKitSDK.cmakeinto your project'scmake/directory.Include the helper in your app's
CMakeLists.txtfile:cmake_minimum_required(VERSION 3.20)project(livekit_cpp_quickstart LANGUAGES CXX)set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")if(LIVEKIT_LOCAL_SDK_DIR)list(PREPEND CMAKE_PREFIX_PATH "${LIVEKIT_LOCAL_SDK_DIR}")else()include(LiveKitSDK)livekit_sdk_setup(VERSION "${LIVEKIT_SDK_VERSION}"SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk"GITHUB_TOKEN "$ENV{GITHUB_TOKEN}")endif()find_package(LiveKit CONFIG REQUIRED)add_executable(example example.cpp)target_link_libraries(example PRIVATE LiveKit::livekit)Configure and build your project:
cmake -S . -B build -DLIVEKIT_SDK_VERSION=latestcmake --build buildPin SDK versionsUse a fixed version from the official C++ SDK releases page for reproducible builds. The
latestoption queries the GitHub API and may needGITHUB_TOKENin CI to avoid rate limits.
Use a local SDK build
You may want to use a local SDK build to use a specific version of the SDK that is not yet released, or to test local changes to the SDK. To build the SDK from source, clone the C++ SDK repository with submodules and install it to a local prefix:
git clone --recurse-submodules https://github.com/livekit/client-sdk-cpp.gitcd client-sdk-cpp# Build the SDK:# --bundle installs the SDK bundle using 'cmake --install'# --prefix specifies where to install the SDK./build.sh release --bundle --prefix "$HOME/livekit-sdk"
Then configure your app with the local install prefix:
cmake -S . -B build -DLIVEKIT_LOCAL_SDK_DIR="$HOME/livekit-sdk"cmake --build build
Connecting to LiveKit
The following example connects to a room and publishes synthetic audio and video tracks. It generates a sine wave and a moving color pattern so you can verify publishing without device capture.
For a production app, make the following changes:
- Generate tokens on your server instead of embedding tokens in the app.
- Replace synthetic media generation with your own camera and microphone capture. For a complete SDL-based example, see
simple_room.
Run an example
Create a file named
example.cppwith the following content:#include <atomic>#include <chrono>#include <cmath>#include <csignal>#include <cstdint>#include <cstdlib>#include <exception>#include <iostream>#include <memory>#include <thread>#include <vector>#include "livekit/livekit.h"namespace {std::atomic<bool> g_running{true};void handleSignal(int) { g_running.store(false); }void generateAudio(const std::shared_ptr<livekit::AudioSource>& audio_source) {constexpr int kSampleRate = 48000;constexpr int kChannels = 1;constexpr int kSamplesPer10Ms = kSampleRate / 100;constexpr double kFrequencyHz = 440.0;constexpr double kPi = 3.14159265358979323846;std::uint64_t sample_index = 0;while (g_running.load()) {std::vector<std::int16_t> samples(kSamplesPer10Ms * kChannels);for (int i = 0; i < kSamplesPer10Ms; ++i) {const double t = static_cast<double>(sample_index++) / kSampleRate;const double value = std::sin(2.0 * kPi * kFrequencyHz * t);samples[i] = static_cast<std::int16_t>(value * 16000.0);}livekit::AudioFrame frame(std::move(samples), kSampleRate, kChannels, kSamplesPer10Ms);audio_source->captureFrame(frame);std::this_thread::sleep_for(std::chrono::milliseconds(10));}}void generateVideo(const std::shared_ptr<livekit::VideoSource>& video_source) {constexpr int kWidth = 1280;constexpr int kHeight = 720;constexpr int kFps = 30;int frame_count = 0;while (g_running.load()) {auto frame = livekit::VideoFrame::create(kWidth, kHeight, livekit::VideoBufferType::RGBA);std::uint8_t* pixels = frame.data();const auto hue = static_cast<std::uint8_t>((frame_count * 2) % 256);for (int y = 0; y < kHeight; ++y) {for (int x = 0; x < kWidth; ++x) {const int offset = (y * kWidth + x) * 4;pixels[offset] = static_cast<std::uint8_t>((x * 255) / kWidth);pixels[offset + 1] = static_cast<std::uint8_t>((y * 255) / kHeight);pixels[offset + 2] = hue;pixels[offset + 3] = 255;}}video_source->captureFrame(frame);++frame_count;std::this_thread::sleep_for(std::chrono::milliseconds(1000 / kFps));}}} // namespaceint main() {const char* url = std::getenv("LIVEKIT_URL");const char* token = std::getenv("LIVEKIT_TOKEN");if (url == nullptr || token == nullptr) {std::cerr << "Set LIVEKIT_URL and LIVEKIT_TOKEN environment variables\n";return 1;}std::signal(SIGINT, handleSignal);livekit::initialize(livekit::LogLevel::Info);auto room = std::make_unique<livekit::Room>();livekit::RoomOptions room_options;room_options.auto_subscribe = true;if (!room->connect(url, token, room_options)) {std::cerr << "Failed to connect\n";livekit::shutdown();return 1;}std::cout << "Connected to room\n";auto audio_source = std::make_shared<livekit::AudioSource>(48000, 1);auto audio_track = livekit::LocalAudioTrack::createLocalAudioTrack("audio", audio_source);livekit::TrackPublishOptions audio_options;audio_options.source = livekit::TrackSource::SOURCE_MICROPHONE;try {if (auto lp = room->localParticipant().lock()) {lp->publishTrack(audio_track, audio_options);}else{std::cerr << "Failed to get local participant\n";return 1;}std::cout << "Published audio track\n";} catch (const std::exception& error) {std::cerr << "Failed to publish audio: " << error.what() << "\n";return 1;}auto video_source = std::make_shared<livekit::VideoSource>(1280, 720);auto video_track = livekit::LocalVideoTrack::createLocalVideoTrack("video", video_source);livekit::TrackPublishOptions video_options;video_options.source = livekit::TrackSource::SOURCE_CAMERA;try {if (auto lp = room->localParticipant().lock()) {lp->publishTrack(video_track, video_options);}else{std::cerr << "Failed to get local participant\n";return 1;}std::cout << "Published video track\n";} catch (const std::exception& error) {std::cerr << "Failed to publish video: " << error.what() << "\n";return 1;}std::thread audio_thread(generateAudio, audio_source);std::thread video_thread(generateVideo, video_source);std::cout << "Streaming synthetic audio and video. Press Ctrl+C to stop.\n";while (g_running.load()) {std::this_thread::sleep_for(std::chrono::milliseconds(100));}if (audio_thread.joinable()) {audio_thread.join();}if (video_thread.joinable()) {video_thread.join();}room.reset();livekit::shutdown();return 0;}Set environment variables with your LiveKit server URL and access token:
export LIVEKIT_URL=wss://your-livekit-server.comexport LIVEKIT_TOKEN=your-access-tokenRun the example:
./build/exampleThe program connects to a LiveKit room and streams a 440 Hz sine wave audio tone and an animated color gradient video. Press
Ctrl+Cto stop.
The SDK accepts raw audio and video frames from your application. It doesn't open the camera or microphone for you. For physical device capture, see the simple_room example, which uses SDL3.
Permissions and entitlements
Most C++ applications don't need operating system permission prompts unless the app accesses physical microphones, cameras, screens, or other devices. Headless or synthetic sources don't require special device permissions.
Microphone or camera capture:
| Operating system | Required permissions |
|---|---|
| macOS | Add NSMicrophoneUsageDescription and NSCameraUsageDescription to your app bundle when applicable. |
| Windows/Linux | Device permissions are typically managed by the OS, desktop session, container runtime, or user group membership. |
Screen capture:
| Operating system | Required permissions |
|---|---|
| macOS | Add Screen Recording permission for your app in System Settings. |
| Windows/Linux | Screen capture permissions are typically managed by the OS, desktop session, display server, or portal implementation. |
Next steps
The following resources are useful for getting started with LiveKit on C++.
Generating tokens
Guide to generating authentication tokens for your users.
Basic room example
Minimal C++ example for connecting and publishing synthetic audio and video.
Simple room example
SDL-based C++ example with real microphone and camera capture.
RPC example
C++ example for registering RPC handlers and calling remote participants.
Data streams example
C++ example for text and byte streams with topics, metadata, and chunked payloads.
C++ SDK
LiveKit C++ SDK source code and releases.
C++ SDK reference
LiveKit C++ SDK reference docs.