diff --git a/Cargo.lock b/Cargo.lock index 236e11f..a29e567 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1807,15 +1807,16 @@ dependencies = [ [[package]] name = "rodio" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d98f5e557b61525057e2bc142c8cd7f0e70d75dc32852309bec440e6e046bf9" +checksum = "ec0939e9f626e6c6f1989adb6226a039c855ca483053f0ee7c98b90e41cf731e" dependencies = [ "claxon", "cpal", "hound", "lewton", "minimp3", + "symphonia", ] [[package]] diff --git a/mps-player/Cargo.toml b/mps-player/Cargo.toml index d582e78..e6549e8 100644 --- a/mps-player/Cargo.toml +++ b/mps-player/Cargo.toml @@ -6,7 +6,7 @@ license = "LGPL-2.1-only OR GPL-2.0-or-later" readme = "README.md" [dependencies] -rodio = { version = "^0.14"} +rodio = { version = "^0.15", features = ["symphonia"]} m3u8-rs = { version = "^3.0.0" } # local diff --git a/mps-player/src/player.rs b/mps-player/src/player.rs index a099d0f..2262bac 100644 --- a/mps-player/src/player.rs +++ b/mps-player/src/player.rs @@ -1,6 +1,5 @@ use std::fs; use std::io; -use std::path::PathBuf; use rodio::{decoder::Decoder, OutputStream, OutputStreamHandle, Sink}; @@ -40,22 +39,11 @@ impl MpsPlayer { if let Some(filename) = music.field("filename").and_then(|x| x.to_owned().to_str()) { - let path: PathBuf = filename.into(); - if let Some(ext) = path.extension().and_then(|x| x.to_str()) { - match ext { - "mp3" - | "wav" - | "flac" - | "aac" - | "ogg" => { - let file = fs::File::open(path).map_err(PlaybackError::from_err)?; - let stream = io::BufReader::new(file); - let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; - self.sink.append(source); - }, - _ => {} - } - } + // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not + let file = fs::File::open(filename).map_err(PlaybackError::from_err)?; + let stream = io::BufReader::new(file); + let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; + self.sink.append(source); Ok(()) } else { Err(PlaybackError::from_err( @@ -79,22 +67,11 @@ impl MpsPlayer { if let Some(filename) = music.field("filename").and_then(|x| x.to_owned().to_str()) { - let path: PathBuf = filename.into(); - if let Some(ext) = path.extension().and_then(|x| x.to_str()) { - match ext { - "mp3" - | "wav" - | "flac" - | "aac" - | "ogg" => { - let file = fs::File::open(path).map_err(PlaybackError::from_err)?; - let stream = io::BufReader::new(file); - let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; - self.sink.append(source); - }, - _ => {} - } - } + // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not + let file = fs::File::open(filename).map_err(PlaybackError::from_err)?; + let stream = io::BufReader::new(file); + let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; + self.sink.append(source); Ok(()) } else { Err(PlaybackError::from_err( @@ -120,24 +97,13 @@ impl MpsPlayer { if let Some(filename) = music.field("filename").and_then(|x| x.to_owned().to_str()) { - let path: PathBuf = filename.into(); - if let Some(ext) = path.extension().and_then(|x| x.to_str()) { - match ext { - "mp3" - | "wav" - | "flac" - | "aac" - | "ogg" => { - enqueued.push(music.clone()); - let file = fs::File::open(path).map_err(PlaybackError::from_err)?; - let stream = io::BufReader::new(file); - let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; - self.sink.append(source); - items_left -= 1; - }, - _ => {} - } - } + enqueued.push(music.clone()); + // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not + let file = fs::File::open(filename).map_err(PlaybackError::from_err)?; + let stream = io::BufReader::new(file); + let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; + self.sink.append(source); + items_left -= 1; Ok(()) } else { Err(PlaybackError::from_err( diff --git a/mps-player/src/player_wrapper.rs b/mps-player/src/player_wrapper.rs index a816c2d..496aeda 100644 --- a/mps-player/src/player_wrapper.rs +++ b/mps-player/src/player_wrapper.rs @@ -39,7 +39,9 @@ impl MpsPlayerServer { fn enqeue_some(&mut self, count: usize) { //println!("Enqueuing up to {} items", count); match self.player.enqueue(count) { - Err(e) => self.event.send(PlayerAction::Exception(e)).unwrap(), + Err(e) => { + self.event.send(PlayerAction::Exception(e)).unwrap(); + }, Ok(items) => { for item in items { // notify of new items that have been enqueued @@ -152,7 +154,7 @@ impl MpsPlayerServer { playback: Sender, keep_alive: bool, ) -> JoinHandle<()> { - thread::spawn(move || Self::unblocking_timer_loop(ctrl_tx, 50)); + thread::spawn(move || Self::unblocking_timer_loop(ctrl_tx, 100)); thread::spawn(move || { let player = factory(); let mut server_obj = Self::new(player, ctrl_rx, event, playback, keep_alive); diff --git a/src/repl.rs b/src/repl.rs index 821cc53..d9b05e7 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -51,10 +51,10 @@ pub fn repl(args: CliArgs) { match player.save_m3u8(&mut playlist_writer) { Ok(_) => {} Err(e) => { - eprintln!("{}", e.message()); + error_prompt(e, &args); // consume any further errors (this shouldn't actually write anything) while let Err(e) = player.save_m3u8(&mut playlist_writer) { - eprintln!("{}", e.message()); + error_prompt(e, &args); } } } @@ -69,7 +69,7 @@ pub fn repl(args: CliArgs) { if args.wait { match ctrl.wait_for_empty() { Ok(_) => {} - Err(e) => eprintln!("{}", e.message()), + Err(e) => error_prompt(e, &args), } } else { // consume all incoming errors @@ -77,7 +77,7 @@ pub fn repl(args: CliArgs) { while had_err { let mut new_had_err = false; for e in ctrl.check_ack() { - eprintln!("{}", e.message()); + error_prompt(e, &args); new_had_err = true; } had_err = new_had_err; @@ -127,7 +127,7 @@ fn read_loop(args: &CliArgs, state: &mut ReplState, mut execute: F) '\n' => { let statement_result = std::str::from_utf8(state.statement_buf.as_slice()); if statement_result.is_ok() && statement_result.unwrap().trim().starts_with("?") { - println!("Got {}", statement_result.unwrap()); + //println!("Got {}", statement_result.unwrap()); repl_commands(statement_result.unwrap().trim()); state.statement_buf.clear(); } else if state.bracket_depth == 0 && state.in_literal.is_none() { @@ -153,6 +153,11 @@ fn prompt(line: &mut usize, args: &CliArgs) { std::io::stdout().flush().expect("Failed to flush stdout"); } +#[inline(always)] +fn error_prompt(error: mps_player::PlaybackError, args: &CliArgs) { + eprintln!("E{}{}", args.prompt, error.message()); +} + fn repl_commands(command_str: &str) { let words: Vec<&str> = command_str.split(" ").map(|s| s.trim()).collect(); match words[0] {