diff --git a/demo/play_file_url/Cargo.toml b/demo/play_file_url/Cargo.toml new file mode 100644 index 0000000..e4dd9d3 --- /dev/null +++ b/demo/play_file_url/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "play_file_url" +version = "0.1.0" +edition = "2021" + +[dependencies] +rodio = { version = "0.19.0", features = ["symphonia-all"] } diff --git a/demo/play_file_url/src/main.rs b/demo/play_file_url/src/main.rs new file mode 100644 index 0000000..f21ddbb --- /dev/null +++ b/demo/play_file_url/src/main.rs @@ -0,0 +1,37 @@ +use std::fs::File; +use std::path::PathBuf; +use std::str::FromStr; +use std::time::Duration; + +use rodio::{Decoder, OutputStream, Source}; +fn main() { + const URL: &str = "file:///home/plex/Musik/Plex/moonwater.mp3"; + let f = open_file_url(URL).unwrap(); + let reader = std::io::BufReader::new(f); + + // Get an output stream handle to the default physical sound device + let (_stream, stream_handle) = OutputStream::try_default().unwrap(); + // Decode that sound file into a source + let source = Decoder::new(reader).unwrap(); + // Play the sound directly on the device + stream_handle.play_raw(source.convert_samples()).unwrap(); + std::thread::sleep(Duration::from_secs(10)); // should be fine, because tokio says + // spawn_blocking happens in another thread +} + +fn open_file_url(url: &str) -> std::io::Result { + if !url.starts_with("file://") { + return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, "bad")); + } + + let path = url.replacen("file://", "", 1); + if let Ok(path) = PathBuf::from_str(&path) { + let f = std::fs::File::open(path)?; + Ok(f) + } else { + Err(std::io::Error::new( + std::io::ErrorKind::Unsupported, + "not a path even without file://", + )) + } +} diff --git a/demo/try_stream/Cargo.toml b/demo/try_stream/Cargo.toml index cf4a034..b2f10bf 100644 --- a/demo/try_stream/Cargo.toml +++ b/demo/try_stream/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" [dependencies] reqwest = "0.12.7" rodio = { version = "0.19.0", features = ["symphonia-all"] } +stream-download = { version = "0.7.2", features = ["reqwest-native-tls"] } tokio = { version = "1.39.3", features = ["rt", "macros"] } diff --git a/demo/try_stream/src/main.rs b/demo/try_stream/src/main.rs index 502121a..88be6d7 100644 --- a/demo/try_stream/src/main.rs +++ b/demo/try_stream/src/main.rs @@ -1,31 +1,39 @@ use std::error::Error; use std::result::Result; +use std::time::Duration; +use reqwest::header::HeaderMap; +use reqwest::Client; use rodio::{Decoder, OutputStream, Source}; +use stream_download::http::HttpStream; +use stream_download::storage::memory::MemoryStorageProvider; +use stream_download::{Settings, StreamDownload}; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box> { - let client = reqwest::Client::new(); - let url = "https://jellyfin.homeserver.box/Items/758d55bf6b122523c9bed78fe8893071/Download?api_key=redacted"; + const URL: &str = "https://upload.wikimedia.org/wikipedia/commons/4/48/Aadama.mp3"; - let res = client - .get(url) - .header("User-Agent", "My Rust Program/1.0") - .send() - .await?; + let mut headers = HeaderMap::new(); + headers.append("User-Agent", "Beatbär Streaming Demo".parse().unwrap()); - let audio_stream = std::io::Cursor::new(res.bytes().await.unwrap()); + let client = Client::builder().default_headers(headers).build()?; - // Get an output stream handle to the default physical sound device - let (_stream, stream_handle) = OutputStream::try_default().unwrap(); - // Decode that sound file into a source - let source = Decoder::new(audio_stream).unwrap(); - // Play the sound directly on the device - stream_handle.play_raw(source.convert_samples()).unwrap(); + let stream = HttpStream::new(client, URL.parse()?).await?; + let reader = + StreamDownload::from_stream(stream, MemoryStorageProvider, Settings::default()).await?; - // The sound plays in a separate audio thread, - // so we need to keep the main thread alive while it's playing. - std::thread::sleep(std::time::Duration::from_secs(5)); + // now play with rodio, or read it out + tokio::task::spawn_blocking(move || { + // Get an output stream handle to the default physical sound device + let (_stream, stream_handle) = OutputStream::try_default().unwrap(); + // Decode that sound file into a source + let source = Decoder::new(reader).unwrap(); + // Play the sound directly on the device + stream_handle.play_raw(source.convert_samples()).unwrap(); + std::thread::sleep(Duration::from_secs(10)); // should be fine, because tokio says + // spawn_blocking happens in another thread + }) + .await?; Ok(()) }