Skip to content

livekit-ffi 0.12.77 (2026-09-08)

Choose a tag to compare

@knope-bot knope-bot released this 08 Sep 18:47
8066415

Features

  • Removes livekit-runtime and converts this package to be tokio only again - #1375 (@1egoman)

Fixes

  • Add data streams v2 to exposed uniffi interface - #1286 (@1egoman)
  • Add the PASSTHROUGH encoding preset and remove the unused UpdateEgressRequest from the generated protocol - #1361 (@frostbyte73)
  • Fix pre-encoded frame segfault on macOS - #1291 (@ladvoc)
  • Handle capture of dmabuf using existing capture path - #1279 (@ladvoc)
  • Add self_test_http_get / self_test_ws_echo / has_http_client / has_ws_client UniFFI exports so foreign hosts can exercise the transport seam end-to-end. - #1290 (@jhugman)

Make AdmProxy worker-thread-affine: all platform ADM access now happens on the WebRTC worker thread, matching the ADM threading contract.

  • The platform ADM is now created lazily on the first PlatformAudio acquire on all platforms, so apps that never use platform audio never construct it.
  • Fixes Android platform recording delivering no audio: the audio transport was never registered on the lazily created ADM.
  • Fixes a shutdown race by keeping the runtime threads alive as long as Rust can reach the audio device controller.
  • Adds a platform_audio example exercising the PlatformAudio API and the worker-thread marshaling. @hiroshihorie

Add agent guidance for detecting and preventing memory-lifecycle regressions in

Rust, FFI, and native WebRTC code. @alan-george-lk

Close peer connections before awaiting signal teardown

SessionInner::close released the peer connections only after two awaits that can block
indefinitely, so cancelling close() — for example by wrapping it in a timeout — left the
transports open and their ICE UDP sockets bound for the lifetime of the process. Long-lived
clients eventually exhausted their file descriptors. The transports are now closed before
the first await, which makes the teardown safe to cancel. @sebitokazu

Moves the internal region-discovery cache into a new livekit-region crate. No

public API or behaviour change. @1egoman

Moves the signalling client into a new livekit-signaling crate. livekit-api

re-exports it under the historical livekit_api::signal_client path, now marked
deprecated: it is internal SDK API, and dependents should use livekit-signaling
directly. livekit-api no longer depends on livekit-net.

Also drops two dependencies that were declared but never used: scopeguard and
bytes. @1egoman

Fix CUDA and FFI resource cleanup during SDK shutdown.

NVIDIA encoder and decoder factories now share a reference-counted CUDA context
and destroy it when the final factory is dropped. FFI shutdown now releases
leftover handles one at a time so nested drop_handle calls do not re-enter
DashMap::clear(). Adds regression coverage for FFI-handle, watcher, and
configuration cleanup during disposal. @alan-george-lk

Expose network_type on IceCandidateStats

Chromium's local RTCIceCandidateStats carries a non-standard networkType field (WiFi,
cellular, ethernet, etc.), but IceCandidateStats had no place to put it, so it was silently
dropped during get_stats() deserialization. Adds network_type: Option<String> to the struct;
non-breaking since it already derives #[serde(default)]. @trypsynth

Fix room-session and data-channel leaks across connect/disconnect cycles.

The E2EE manager callback now captures RoomSession weakly so the session can
drop after disconnect. Data-channel observer callbacks are cleared during RTC
teardown so the observer/callback cycle cannot keep peer connections alive.
Adds regression coverage for room-session destruction and data-channel callback
cleanup. @alan-george-lk @raparanjpe

Fix native video-source lifecycle and NVENC initialization failure handling.

The raw-video keepalive task now uses a weak liveness check and defers its
black I420 buffer allocation until source liveness is confirmed, so dropping
an unused source releases its resources. nvEncInitializeEncoder failures now
propagate instead of leaving the encoder half-initialized. @alan-george-lk