Skip to content

denniskribl/oxicast

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

πŸ›°οΈ oxicast

Async Google Cast (Chromecast) client for Rust β€” discover, connect, and control Cast devices with tokio.

crates.io docs.rs CI Coverage License

Quickstart Β· API Docs Β· Examples Β· Guide


What is this?

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?;

πŸš€ Quickstart

1. Install

[dependencies]
oxicast = "0.0.3"
tokio = { version = "1", features = ["full"] }

2. Connect and play

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?;

✨ Features

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)

Feature flags

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"] }

πŸ“– Documentation

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

πŸ“‚ Examples

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-features

License

Licensed under either of Apache License 2.0 or MIT at your option.


Trademarks

Google Cast and Chromecast are trademarks of Google LLC. This project is not affiliated with or endorsed by Google.

About

Async Google Cast (Chromecast) client for Rust, built on tokio

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages