Skip to content

README

This page mirrors the GitHub README. For the full docs, use the sidebar.

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).await?;
client.pause().await?;
client.seek(60.0).await?;
client.play().await?;

[dependencies]
oxicast = "0.0.1"
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,
).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?;

FeatureDescription
🔌 Async-nativeBuilt on tokio — full async/await, no blocking calls
💓 Auto heartbeatPING/PONG managed invisibly in the background
Instant commandsSeparate reader/writer tasks — commands never wait for the read loop
📊 Reactive statuswatch channels for always-fresh media and receiver state
🔄 Auto-reconnectExponential backoff with jitter, serialized with manual reconnect
🔍 mDNS discoveryScan the network or stream devices as they appear
🛡️ Typed errorsStructured enum for connection, protocol, and media failures
🧵 Thread-safeClone + Send + Sync — share across tasks freely
📁 Local file castingBuilt-in HTTP server serves files to Chromecast (opt-in serve feature)
FlagDefaultWhat it adds
discoverymDNS device scanning via mdns-sd
serveHTTP file server for casting local files
# Disable discovery, enable local file serving
oxicast = { version = "0.0.1", default-features = false, features = ["serve"] }

DocumentDescription
Getting StartedConnect, discover, play media, handle events
API OverviewFull API surface with code examples
ArchitectureSplit-stream reactor, task lifecycle, reconnect, event delivery
Error HandlingError enum, device errors, timeouts
CHANGELOGVersion history

ExampleWhat it does
discover_and_playmDNS scan, connect, load HLS stream, monitor events
media_controlPause, seek, volume, resume
event_monitorPrint all events in real-time
custom_namespaceSend/receive on custom namespaces
device_test14-step integration test against real hardware
Terminal window
# 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-features

Licensed 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.