
Line-by-line transliteration of upstream SDK delivering real-time video, audio and data channels, simulcast, SVC codecs, hardware-accelerated encoding/decoding, and server APIs.
This is a Kotlin Multiplatform line-by-line transliteration port of livekit/rust-sdks.
Original Project: This port is based on livekit/rust-sdks. All design credit and project intent belong to the upstream authors; this repository is a faithful port to Kotlin Multiplatform with no behavioural changes intended.
This is an in-progress port. The goal is feature parity with the upstream Rust crate while providing a native Kotlin Multiplatform API. Every Kotlin file carries a // port-lint: source <path> header naming its upstream Rust counterpart so the AST-distance tool can track provenance.
The text below is reproduced and lightly edited from
https://github.com/livekit/rust-sdks. It is the upstream project's own description and remains under the upstream authors' authorship; links have been rewritten to absolute upstream URLs so they continue to resolve from this repository.
Use this SDK to add realtime video, audio and data features to your Rust app. By connecting to LiveKit Cloud or a self-hosted server, you can quickly build applications such as multi-modal AI, live streaming, or video calls with just a few lines of code.
livekit-api: Server APIs and auth token generationlivekit: LiveKit real-time SDKlivekit-ffi: Internal crate, used to generate bindings for other languageslivekit-protocol: LiveKit protocol generated codeWhen adding the SDK as a dependency to your project, make sure to add the
necessary rustflags
to your cargo config, otherwise linking may fail.
Also, please refer to the list of the supported platform toolkits.
Currently, Tokio is required to use this SDK, however we plan to make the async executor runtime agnostic.
use livekit_api::access_token;
use std::env;
fn create_token() -> Result<String, access_token::AccessTokenError> {
let api_key = env::var("LIVEKIT_API_KEY").expect("LIVEKIT_API_KEY is not set");
let api_secret = env::var("LIVEKIT_API_SECRET").expect("LIVEKIT_API_SECRET is not set");
let token = access_token::AccessToken::with_api_key(&api_key, &api_secret)
.with_identity("rust-bot")
.with_name("Rust Bot")
.with_grants(access_token::VideoGrants {
room_join: true,
room: "my-room".to_string(),
..Default::default()
})
.to_jwt();
return token
}use livekit_api::services::room::{CreateRoomOptions, RoomClient};
#[tokio::main]
async fn main() {
let room_service = RoomClient::new("http://localhost:7880").unwrap();
let room = room_service
.create_room("my_room", CreateRoomOptions::default())
.await
.unwrap();
println!("Created room: {:?}", room);
}use livekit::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
let (room, mut room_events) = Room::connect(&url, &token).await?;
while let Some(event) = room_events.recv().await {
match event {
RoomEvent::TrackSubscribed { track, publication, participant } => {
// ...
}
_ => {}
}
}
Ok(())
}...
use futures::StreamExt; // this trait is required for iterating on audio & video frames
use livekit::prelude::*;
match event {
RoomEvent::TrackSubscribed { track, publication, participant } => {
match track {
RemoteTrack::Audio(audio_track) => {
let rtc_track = audio_track.rtc_track();
let mut audio_stream = NativeAudioStream::new(rtc_track);
tokio::spawn(async move {
// Receive the audio frames in a new task
while let Some(audio_frame) = audio_stream.next().await {
log::info!("received audio frame - {audio_frame:#?}");
}
});
},
RemoteTrack::Video(video_track) => {
let rtc_track = video_track.rtc_track();
let mut video_stream = NativeVideoStream::new(rtc_track);
tokio::spawn(async move {
// Receive the video frames in a new task
while let Some(video_frame) = video_stream.next().await {
log::info!("received video frame - {video_frame:#?}");
}
});
},
}
},
_ => {}
}When building on MacOS, -ObjC linker flag is needed. LiveKit's WebRTC implementation make use of ObjectiveC libraries on the Mac. You may get the following error if the app isn't linked with ObjC:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RTCVideoCodecInfo nativeSdpVideoFormat]: unrecognized selector sent to instance 0x600003bc6660'
LiveKit aims to provide an open source, end-to-end WebRTC stack that works everywhere. We have two goals in mind with this SDK:
Regarding (2), we've already developed a number of client SDKs for several platforms and encountered a few challenges in the process:
Thus, we posited a Rust SDK, something we wanted build anyway, encapsulating all our business logic and platform-specific APIs into a clean set of abstractions, could also serve as the foundation for our other SDKs!
We'll first use it as a basis for our Unity SDK (under development), but over time, it will power our other SDKs, as well.
| LiveKit Ecosystem | |
|---|---|
| Agents SDKs | Python · Node.js |
| LiveKit SDKs | Browser · Swift · Android · Flutter · React Native · Rust · Node.js · Python · Unity · Unity (WebGL) · ESP32 · C++ |
| Starter Apps | Python Agent · TypeScript Agent · React App · SwiftUI App · Android App · Flutter App · React Native App · Web Embed |
| UI Components | React · Android Compose · SwiftUI · Flutter |
| Server APIs | Node.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (community) · .NET (community) |
| Resources | Docs · Docs MCP Server · CLI · LiveKit Cloud |
| LiveKit Server OSS | LiveKit server · Egress · Ingress · SIP |
| Community | Developer Community · Slack · X · YouTube |
dependencies {
implementation("io.github.kotlinmania:libwebrtc-kotlin:0.1.1")
}./gradlew build
./gradlew testSee AGENTS.md and CLAUDE.md for translator discipline, port-lint header convention, and Rust → Kotlin idiom mapping.
This Kotlin port is distributed under the same Apache-2.0 license as the upstream livekit/rust-sdks. See LICENSE (and any sibling LICENSE-* / NOTICE files mirrored from upstream) for the full text.
Original work copyrighted by the rust-sdks authors.
Kotlin port: Copyright (c) 2026 Sydney Renee and The Solace Project.
Thanks to the livekit/rust-sdks maintainers and contributors for the original Rust implementation. This port reproduces their work in Kotlin Multiplatform; bug reports about upstream design or behavior should go to the upstream repository.
This is a Kotlin Multiplatform line-by-line transliteration port of livekit/rust-sdks.
Original Project: This port is based on livekit/rust-sdks. All design credit and project intent belong to the upstream authors; this repository is a faithful port to Kotlin Multiplatform with no behavioural changes intended.
This is an in-progress port. The goal is feature parity with the upstream Rust crate while providing a native Kotlin Multiplatform API. Every Kotlin file carries a // port-lint: source <path> header naming its upstream Rust counterpart so the AST-distance tool can track provenance.
The text below is reproduced and lightly edited from
https://github.com/livekit/rust-sdks. It is the upstream project's own description and remains under the upstream authors' authorship; links have been rewritten to absolute upstream URLs so they continue to resolve from this repository.
Use this SDK to add realtime video, audio and data features to your Rust app. By connecting to LiveKit Cloud or a self-hosted server, you can quickly build applications such as multi-modal AI, live streaming, or video calls with just a few lines of code.
livekit-api: Server APIs and auth token generationlivekit: LiveKit real-time SDKlivekit-ffi: Internal crate, used to generate bindings for other languageslivekit-protocol: LiveKit protocol generated codeWhen adding the SDK as a dependency to your project, make sure to add the
necessary rustflags
to your cargo config, otherwise linking may fail.
Also, please refer to the list of the supported platform toolkits.
Currently, Tokio is required to use this SDK, however we plan to make the async executor runtime agnostic.
use livekit_api::access_token;
use std::env;
fn create_token() -> Result<String, access_token::AccessTokenError> {
let api_key = env::var("LIVEKIT_API_KEY").expect("LIVEKIT_API_KEY is not set");
let api_secret = env::var("LIVEKIT_API_SECRET").expect("LIVEKIT_API_SECRET is not set");
let token = access_token::AccessToken::with_api_key(&api_key, &api_secret)
.with_identity("rust-bot")
.with_name("Rust Bot")
.with_grants(access_token::VideoGrants {
room_join: true,
room: "my-room".to_string(),
..Default::default()
})
.to_jwt();
return token
}use livekit_api::services::room::{CreateRoomOptions, RoomClient};
#[tokio::main]
async fn main() {
let room_service = RoomClient::new("http://localhost:7880").unwrap();
let room = room_service
.create_room("my_room", CreateRoomOptions::default())
.await
.unwrap();
println!("Created room: {:?}", room);
}use livekit::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
let (room, mut room_events) = Room::connect(&url, &token).await?;
while let Some(event) = room_events.recv().await {
match event {
RoomEvent::TrackSubscribed { track, publication, participant } => {
// ...
}
_ => {}
}
}
Ok(())
}...
use futures::StreamExt; // this trait is required for iterating on audio & video frames
use livekit::prelude::*;
match event {
RoomEvent::TrackSubscribed { track, publication, participant } => {
match track {
RemoteTrack::Audio(audio_track) => {
let rtc_track = audio_track.rtc_track();
let mut audio_stream = NativeAudioStream::new(rtc_track);
tokio::spawn(async move {
// Receive the audio frames in a new task
while let Some(audio_frame) = audio_stream.next().await {
log::info!("received audio frame - {audio_frame:#?}");
}
});
},
RemoteTrack::Video(video_track) => {
let rtc_track = video_track.rtc_track();
let mut video_stream = NativeVideoStream::new(rtc_track);
tokio::spawn(async move {
// Receive the video frames in a new task
while let Some(video_frame) = video_stream.next().await {
log::info!("received video frame - {video_frame:#?}");
}
});
},
}
},
_ => {}
}When building on MacOS, -ObjC linker flag is needed. LiveKit's WebRTC implementation make use of ObjectiveC libraries on the Mac. You may get the following error if the app isn't linked with ObjC:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RTCVideoCodecInfo nativeSdpVideoFormat]: unrecognized selector sent to instance 0x600003bc6660'
LiveKit aims to provide an open source, end-to-end WebRTC stack that works everywhere. We have two goals in mind with this SDK:
Regarding (2), we've already developed a number of client SDKs for several platforms and encountered a few challenges in the process:
Thus, we posited a Rust SDK, something we wanted build anyway, encapsulating all our business logic and platform-specific APIs into a clean set of abstractions, could also serve as the foundation for our other SDKs!
We'll first use it as a basis for our Unity SDK (under development), but over time, it will power our other SDKs, as well.
| LiveKit Ecosystem | |
|---|---|
| Agents SDKs | Python · Node.js |
| LiveKit SDKs | Browser · Swift · Android · Flutter · React Native · Rust · Node.js · Python · Unity · Unity (WebGL) · ESP32 · C++ |
| Starter Apps | Python Agent · TypeScript Agent · React App · SwiftUI App · Android App · Flutter App · React Native App · Web Embed |
| UI Components | React · Android Compose · SwiftUI · Flutter |
| Server APIs | Node.js · Golang · Ruby · Java/Kotlin · Python · Rust · PHP (community) · .NET (community) |
| Resources | Docs · Docs MCP Server · CLI · LiveKit Cloud |
| LiveKit Server OSS | LiveKit server · Egress · Ingress · SIP |
| Community | Developer Community · Slack · X · YouTube |
dependencies {
implementation("io.github.kotlinmania:libwebrtc-kotlin:0.1.1")
}./gradlew build
./gradlew testSee AGENTS.md and CLAUDE.md for translator discipline, port-lint header convention, and Rust → Kotlin idiom mapping.
This Kotlin port is distributed under the same Apache-2.0 license as the upstream livekit/rust-sdks. See LICENSE (and any sibling LICENSE-* / NOTICE files mirrored from upstream) for the full text.
Original work copyrighted by the rust-sdks authors.
Kotlin port: Copyright (c) 2026 Sydney Renee and The Solace Project.
Thanks to the livekit/rust-sdks maintainers and contributors for the original Rust implementation. This port reproduces their work in Kotlin Multiplatform; bug reports about upstream design or behavior should go to the upstream repository.