|
LiveKit C++ Client SDK v1.13.0
Real-time audio/video/data SDK for C++
|
NOTE: LiveKit Capture is not officially supported on Intel-based Macs.
livekit::capture::CaptureSource connects a Rust video producer to a regular C++ VideoSource. The capture pump runs in Rust, so C++ does not send one FFI request per frame. The SDK supports three source configurations:
| Configuration | Output | Runtime requirements |
|---|---|---|
PatternVideoSourceConfig | GPU-rendered gradient or LiveKit logo | Compatible GPU adapter |
ClockVideoSourceConfig | GPU-rendered local time with millisecond precision | Compatible GPU adapter |
GstreamerVideoSourceConfig | Pre-encoded video from a GStreamer pipeline | GStreamer runtime and the pipeline's plugins |
A custom SDK build can include all sources or a subset selected with --capture=pattern,clock or --capture=gstreamer. Release -capture bundles include all sources. LIVEKIT_CAPTURE_ENABLED indicates that at least one source is enabled; creating a source omitted from the build reports a std::runtime_error through the returned future. Pattern/clock-only builds do not require GStreamer.
Native camera device capture and device enumeration are not part of this API.
For build flags, release bundle naming, GStreamer prerequisites, and runtime requirements, see Building — Capture sources.
Capture types live in the livekit::capture namespace. Capture-enabled bundles install the API in include/livekit/capture/:
Standard SDK bundles omit the capture/ directory, and their other installed headers do not name it.
Rust validates capture configurations, including zero dimensions and frame rates, and reports failures as std::runtime_error when the returned future is awaited. Resolution dimensions use std::uint32_t, matching the protobuf and Rust types. The C++ wrapper rejects invalid enum values that cannot be serialized, using std::invalid_argument. For GStreamer, resolution and codec can be omitted to discover them from negotiated pipeline caps. Producer setup failures reported by Rust also throw std::runtime_error through that future.
Discarding a creation future does not wait for creation to finish. Creation continues, and the source is released when the callback arrives.
Keep capture alive while its track is published. stop() signals the pump to finish without waiting. join() consumes the running pump, waits for its thread to exit, and reports the exit reason and frame count. For unbounded sources, call stop() before join(). Destroying the source also stops capture.
Provide appsink name=lk_appsink, or leave exactly one encoded video source pad unlinked so the source can attach its own sink:
The optional rate-control binding forwards WebRTC bitrate targets to the named encoder property. Without it, the pipeline uses its configured fixed bitrate. Use capture->publishOptions() when publishing: encoded sources require the source's codec, the PreEncoded encoder, and disabled simulcast, which override conflicting application options. All other application options are preserved. Pattern and clock sources preserve every application option, including explicit codec and simulcast choices. Rust supplies defaults for fields left unset.
CaptureErrorKind matches the protobuf enum exactly:
| C++ value | Protobuf value | Meaning |
|---|---|---|
Source = 0 | CAPTURE_ERROR_KIND_SOURCE = 0 | The running capture source failed or violated its contract. |
Rtc = 1 | CAPTURE_ERROR_KIND_RTC = 1 | The RTC source rejected a frame. |
Panicked = 2 | CAPTURE_ERROR_KIND_PANICKED = 2 | The pump thread panicked. |
A structured pump error received from Rust becomes a failed Result<CaptureResult, CaptureError> from join(). Its message and kind are preserved. Check the result before calling value() or error().
Failures without a protobuf error kind throw a clear exception with the operation name and diagnostic. Invalid enum values that cannot be serialized throw std::invalid_argument. Rust configuration validation errors, uninitialized SDK use, transport failures, malformed responses, shutdown cancellation, and untyped errors from Rust throw std::runtime_error. create() and join() deliver these exceptions from the returned future's get(); start() and stop() throw directly. Exceptions are captured at the FFI callback boundary. They never unwind through Rust callbacks.
| Operation | Return type | Failure handling |
|---|---|---|
create(config) | std::future<Result<std::shared_ptr<CaptureSource>, CaptureError>> | Configuration and untyped setup errors throw from get(). |
start() / stop() | Result<void, CaptureError> | Current control responses carry untyped strings, so rejection throws directly. |
join() | std::future<Result<CaptureResult, CaptureError>> | Structured pump errors use error(); binding failures throw from get(). |
CaptureResult contains successful statistics only. Creation and control return successful results when their requests succeed; the current protocol supplies structured error kinds only for the terminal pump result. The SDK does not classify untyped Rust messages by parsing their text. Allocation failures may also throw.