generated from PlexSheep/rs-base
feat: get the http streamer and file streamer demos to work
cargo devel CI / cargo CI (push) Failing after 1m6s
Details
cargo devel CI / cargo CI (push) Failing after 1m6s
Details
This commit is contained in:
parent
e068450b6b
commit
234e2743ad
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "play_file_url"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rodio = { version = "0.19.0", features = ["symphonia-all"] }
|
|
@ -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<File> {
|
||||||
|
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://",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,4 +6,5 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = "0.12.7"
|
reqwest = "0.12.7"
|
||||||
rodio = { version = "0.19.0", features = ["symphonia-all"] }
|
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"] }
|
tokio = { version = "1.39.3", features = ["rt", "macros"] }
|
||||||
|
|
|
@ -1,31 +1,39 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use reqwest::header::HeaderMap;
|
||||||
|
use reqwest::Client;
|
||||||
use rodio::{Decoder, OutputStream, Source};
|
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")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let client = reqwest::Client::new();
|
const URL: &str = "https://upload.wikimedia.org/wikipedia/commons/4/48/Aadama.mp3";
|
||||||
let url = "https://jellyfin.homeserver.box/Items/758d55bf6b122523c9bed78fe8893071/Download?api_key=redacted";
|
|
||||||
|
|
||||||
let res = client
|
let mut headers = HeaderMap::new();
|
||||||
.get(url)
|
headers.append("User-Agent", "Beatbär Streaming Demo".parse().unwrap());
|
||||||
.header("User-Agent", "My Rust Program/1.0")
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
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 = HttpStream::new(client, URL.parse()?).await?;
|
||||||
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
|
let reader =
|
||||||
// Decode that sound file into a source
|
StreamDownload::from_stream(stream, MemoryStorageProvider, Settings::default()).await?;
|
||||||
let source = Decoder::new(audio_stream).unwrap();
|
|
||||||
// Play the sound directly on the device
|
|
||||||
stream_handle.play_raw(source.convert_samples()).unwrap();
|
|
||||||
|
|
||||||
// The sound plays in a separate audio thread,
|
// now play with rodio, or read it out
|
||||||
// so we need to keep the main thread alive while it's playing.
|
tokio::task::spawn_blocking(move || {
|
||||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue