Skip to content
Open
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
67 changes: 59 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,72 @@
# Copyright 2026 LiveKit, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.20)
project(livekit_cpp_example_collection LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Make "include(LiveKitSDK)" search in ./cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

set(LIVEKIT_SDK_VERSION "latest" CACHE STRING "LiveKit C++ SDK version (e.g. 0.2.0 or latest)")
set(LIVEKIT_LOCAL_SDK_DIR "" CACHE PATH "Path to a local LiveKit SDK install prefix (skips download)")

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(LiveKitSDK)
if(LIVEKIT_LOCAL_SDK_DIR)
message(STATUS "Using local LiveKit SDK: ${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)

livekit_sdk_setup(
VERSION "${LIVEKIT_SDK_VERSION}"
SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk"
GITHUB_TOKEN "$ENV{GITHUB_TOKEN}"
)
if(TARGET LiveKit::livekit)
set(LIVEKIT_CORE_TARGET LiveKit::livekit)
elseif(TARGET livekit)
set(LIVEKIT_CORE_TARGET livekit)
else()
message(FATAL_ERROR "Could not find a LiveKit core target (expected LiveKit::livekit or livekit).")
endif()

if(DEFINED _SPDLOG_ACTIVE_LEVEL AND NOT "${_SPDLOG_ACTIVE_LEVEL}" STREQUAL "")
add_compile_definitions(SPDLOG_ACTIVE_LEVEL=${_SPDLOG_ACTIVE_LEVEL})
else()
add_compile_definitions(SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_INFO)
endif()

set(LIVEKIT_DATA_DIR "")
if(DEFINED LIVEKIT_ROOT_DIR AND EXISTS "${LIVEKIT_ROOT_DIR}/data")
set(LIVEKIT_DATA_DIR "${LIVEKIT_ROOT_DIR}/data")
endif()

include(ExampleDeps)

find_package(LiveKit CONFIG REQUIRED)
add_subdirectory(basic_room)
add_subdirectory(simple_room)
add_subdirectory(simple_rpc)
add_subdirectory(simple_data_stream)
add_subdirectory(logging_levels/basic_usage)
add_subdirectory(logging_levels/custom_sinks)
add_subdirectory(hello_livekit/sender)
add_subdirectory(hello_livekit/receiver)
add_subdirectory(simple_joystick/sender)
add_subdirectory(simple_joystick/receiver)
add_subdirectory(ping_pong/ping)
add_subdirectory(ping_pong/pong)
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The goal of these examples is to demonstrate common usage patterns of the
LiveKit C++ SDK (connecting to a room, publishing tracks, RPC, data streams,
etc.) without requiring users to build the SDK from source.

Related examples are grouped under shared folders. For example, the ping-pong
examples now live under `ping_pong/`, and paired sender/receiver examples are
grouped together similarly.


## How the SDK is provided

Expand Down Expand Up @@ -35,6 +39,16 @@ rm -rf build
cmake -S . -B build -DLIVEKIT_SDK_VERSION=0.3.1
```

Build against a local SDK:
```bash
rm -rf build
# install the SDK into $HOME/livekit-sdk-install (or any other directory)
cmake --install <sdk-build-dir> --prefix $HOME/livekit-sdk-install

# build the examples against the local SDK
cmake -S . -B build -DLIVEKIT_LOCAL_SDK_DIR=$HOME/livekit-sdk-install
```


### Building the examples
#### macOS / Linux
Expand All @@ -53,21 +67,27 @@ The Livekit Release SDK is downloaded into **build/_deps/livekit-sdk/**

### Running the examples

After building, example binaries are located under:
After building, example binaries are located under their corresponding build
subdirectories:
```bash
build/<example-name>/
build/<example-path>/
```

For example:
```bash
./build/basic_room/basic_room --url <ws-url> --token <token>
```

Grouped examples follow the same pattern, for example:
```bash
./build/ping_pong/ping/PingPongPing --url <ws-url> --token <token>
```

### Supported platforms

Prebuilt SDKs are downloaded automatically for:
* Windows: x64
* macOS: x64, arm64 (Apple Silicon)
* Linux: x64

If no matching SDK is available for your platform, CMake configuration will fail with a clear error.
If no matching SDK is available for your platform, CMake configuration will fail with a clear error.
15 changes: 14 additions & 1 deletion basic_room/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2026 LiveKit, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

add_executable(basic_room
main.cpp
capture_utils.cpp
Expand All @@ -13,7 +27,6 @@ get_filename_component(_lk_lib_dir "${_lk_cmake_dir}" DIRECTORY) # .../lib
target_link_directories(basic_room PRIVATE "${_lk_lib_dir}")



# Nice-to-have: copy runtime DLLs next to the exe on Windows for "run from build dir".
# Only do this if your exported package provides these targets.
if(WIN32)
Expand Down
24 changes: 11 additions & 13 deletions basic_room/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ void printUsage(const char *prog) {
<< " LIVEKIT_URL, LIVEKIT_TOKEN\n";
}

bool parseArgs(int argc, char *argv[], std::string &url, std::string &token, bool &self_test) {
bool parseArgs(int argc, char *argv[], std::string &url, std::string &token,
bool &self_test) {
for (int i = 1; i < argc; ++i) {
const std::string a = argv[i];
if (a == "-h" || a == "--help")
Expand Down Expand Up @@ -85,14 +86,9 @@ bool parseArgs(int argc, char *argv[], std::string &url, std::string &token, boo
}

void print_livekit_version() {
std::cout
<< "LiveKit version: "
<< LIVEKIT_BUILD_VERSION_FULL
<< " (" << LIVEKIT_BUILD_FLAVOR
<< ", commit " << LIVEKIT_BUILD_COMMIT
<< ", built " << LIVEKIT_BUILD_DATE
<< ")"
<< std::endl;
std::cout << "LiveKit version: " << LIVEKIT_BUILD_VERSION_FULL << " ("
<< LIVEKIT_BUILD_FLAVOR << ", commit " << LIVEKIT_BUILD_COMMIT
<< ", built " << LIVEKIT_BUILD_DATE << ")" << std::endl;
}

} // namespace
Expand All @@ -106,7 +102,7 @@ int main(int argc, char *argv[]) {
return 1;
}
if (self_test) {
livekit::initialize(livekit::LogSink::kConsole);
livekit::initialize(livekit::LogLevel::Info, livekit::LogSink::kConsole);
livekit::shutdown();
std::cout << "self-test ok" << std::endl;
return 0;
Expand All @@ -115,7 +111,7 @@ int main(int argc, char *argv[]) {
std::signal(SIGINT, handleSignal);

// Init LiveKit
livekit::initialize(livekit::LogSink::kConsole);
livekit::initialize(livekit::LogLevel::Info, livekit::LogSink::kConsole);

auto room = std::make_unique<Room>();

Expand Down Expand Up @@ -145,7 +141,8 @@ int main(int argc, char *argv[]) {

std::shared_ptr<LocalTrackPublication> audioPub;
try {
audioPub = room->localParticipant()->publishTrack(audioTrack, audioOpts);
room->localParticipant()->publishTrack(audioTrack, audioOpts);
audioPub = audioTrack->publication();
std::cout << "Published audio: sid=" << audioPub->sid() << "\n";
} catch (const std::exception &e) {
std::cerr << "Failed to publish audio: " << e.what() << "\n";
Expand All @@ -163,7 +160,8 @@ int main(int argc, char *argv[]) {

std::shared_ptr<LocalTrackPublication> videoPub;
try {
videoPub = room->localParticipant()->publishTrack(videoTrack, videoOpts);
room->localParticipant()->publishTrack(videoTrack, videoOpts);
videoPub = videoTrack->publication();
std::cout << "Published video: sid=" << videoPub->sid() << "\n";
} catch (const std::exception &e) {
std::cerr << "Failed to publish video: " << e.what() << "\n";
Expand Down
51 changes: 51 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Copyright 2026 LiveKit
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -euo pipefail

usage() {
cat <<EOF
Usage: ./build.sh [clean] [--help] [CMAKE_ARGS...]

Options:
clean Remove the build directory before building
--help, -h Show this help message and exit

Extra arguments are forwarded to cmake, e.g.:
./build.sh -DLIVEKIT_SDK_VERSION=0.3.0
./build.sh clean -DCMAKE_BUILD_TYPE=Release
./build.sh -DLIVEKIT_LOCAL_SDK_DIR=<path-to-local-sdk-install-prefix>
EOF
}

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="${SCRIPT_DIR}/build"

if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
usage
exit 0
fi

if [[ "${1:-}" == "clean" ]]; then
echo "Removing ${BUILD_DIR} ..."
rm -rf "${BUILD_DIR}"
shift
fi

mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"

cmake "${SCRIPT_DIR}" "$@"
cmake --build . --parallel
30 changes: 30 additions & 0 deletions cmake/ExampleDeps.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
include(FetchContent)

find_package(nlohmann_json CONFIG QUIET)
if(NOT TARGET nlohmann_json::nlohmann_json)
FetchContent_Declare(
nlohmann_json
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
)
FetchContent_MakeAvailable(nlohmann_json)
endif()

find_package(SDL3 CONFIG QUIET)
set(_need_sdl3_fetch TRUE)
if(TARGET SDL3::SDL3)
get_target_property(_sdl3_include_dirs SDL3::SDL3 INTERFACE_INCLUDE_DIRECTORIES)
if(_sdl3_include_dirs)
set(_need_sdl3_fetch FALSE)
endif()
endif()

if(_need_sdl3_fetch)
FetchContent_Declare(
SDL3
URL https://github.com/libsdl-org/SDL/releases/download/release-3.2.26/SDL3-3.2.26.tar.gz
)
FetchContent_MakeAvailable(SDL3)
endif()

unset(_need_sdl3_fetch)
unset(_sdl3_include_dirs)
20 changes: 20 additions & 0 deletions hello_livekit/receiver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2026 LiveKit, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

add_executable(HelloLivekitReceiver
main.cpp
)

target_include_directories(HelloLivekitReceiver PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(HelloLivekitReceiver PRIVATE ${LIVEKIT_CORE_TARGET})
Loading
Loading