Async Google Cast (Chromecast) client for Rust β discover, connect, and control Cast devices with tokio.
Quickstart Β· API Docs Β· Examples Β· Guide
A fully async Rust client for the Google Cast protocol (Chromecast, Google TV, Cast-enabled speakers). Connect by IP or discover devices via mDNS, launch apps, load media, control playback, and react to device events β all through a clean async/await API built on tokio.
let client = CastClient::connect("192.168.1.100", 8009).await?;
client.launch_app(&CastApp::DefaultMediaReceiver).await?;
client.load_media(&MediaInfo::new(url, "video/mp4"), true, 0.0, None).await?;
client.pause().await?;
client.seek(60.0).await?;
client.play().await?;[dependencies]
oxicast = "0.0.3"
tokio = { version = "1", features = ["full"] }use oxicast::{CastClient, CastApp, CastEvent, MediaInfo};
use std::time::Duration;
#[tokio::main]
async fn main() -> oxicast::Result<()> {
// Discover devices on the network
let devices = oxicast::discovery::discover_devices(Duration::from_secs(3)).await?;
let device = match devices.first() {
Some(d) => d,
None => { eprintln!("No devices found"); return Ok(()); }
};
println!("Found: {} at {}", device.name, device.ip);
// Connect and play
let client = CastClient::connect(&device.ip.to_string(), device.port).await?;
client.launch_app(&CastApp::DefaultMediaReceiver).await?;
client.load_media(
&MediaInfo::new("https://example.com/video.mp4", "video/mp4"),
true, 0.0,
None,
).await?;
// React to events
loop {
tokio::select! {
Some(event) = client.next_event() => match event {
CastEvent::MediaStatusChanged(s) => {
println!("{:?} at {:.1}s", s.player_state, s.current_time);
}
CastEvent::Disconnected(_) => break,
_ => {}
},
_ = tokio::signal::ctrl_c() => {
client.disconnect().await?;
break;
}
}
}
Ok(())
}Or connect directly by IP β discovery is optional:
let client = CastClient::connect("192.168.1.100", 8009).await?;| Feature | Description |
|---|---|
| π Async-native | Built on tokio β full async/await, no blocking calls |
| π Auto heartbeat | PING/PONG managed invisibly in the background |
| β‘ Instant commands | Separate reader/writer tasks β commands never wait for the read loop |
| π Reactive status | watch channels for always-fresh media and receiver state |
| π Auto-reconnect | Exponential backoff with jitter, serialized with manual reconnect |
| π mDNS discovery | Scan the network or stream devices as they appear |
| π‘οΈ Typed errors | Structured enum for connection, protocol, and media failures |
| π§΅ Thread-safe | Clone + Send + Sync β share across tasks freely |
| π Local file casting | Built-in HTTP server serves files to Chromecast (opt-in serve feature) |
| Flag | Default | What it adds |
|---|---|---|
discovery |
β | mDNS device scanning via mdns-sd |
serve |
β | HTTP file server for casting local files |
# Disable discovery, enable local file serving
oxicast = { version = "0.0.3", default-features = false, features = ["serve"] }| Document | Description |
|---|---|
| Getting Started | Connect, discover, play media, handle events |
| API Overview | Full API surface with code examples |
| Architecture | Split-stream reactor, task lifecycle, reconnect, event delivery |
| Error Handling | Error enum, device errors, timeouts |
| CHANGELOG | Version history |
| Example | What it does |
|---|---|
discover_and_play |
mDNS scan, connect, load HLS stream, monitor events |
media_control |
Pause, seek, volume, resume |
event_monitor |
Print all events in real-time |
custom_namespace |
Send/receive on custom namespaces |
device_test |
14-step integration test against real hardware |
# Run the device test (auto-discovers or pass IP)
cargo run --example device_test --all-features
cargo run --example device_test --all-features -- 192.168.1.100
# With protocol-level tracing
RUST_LOG=oxicast=trace cargo run --example device_test --all-featuresLicensed under either of Apache License 2.0 or MIT at your option.
Google Cast and Chromecast are trademarks of Google LLC. This project is not affiliated with or endorsed by Google.