diff --git a/src/bin/client/commands/cursor_move.rs b/src/bin/client/commands/cursor_move.rs index 2e9529b..26e63aa 100644 --- a/src/bin/client/commands/cursor_move.rs +++ b/src/bin/client/commands/cursor_move.rs @@ -72,26 +72,26 @@ fn set_curr_dirlist_index(context: &mut AppContext, new_index: usize) { pub fn get_playlist_index(context: &AppContext) -> Option { context .server_state_ref() - .player_ref() - .playlist_ref() + .player + .playlist .get_cursor_index() } fn get_playlist_len(context: &AppContext) -> usize { - context.server_state_ref().player_ref().playlist_ref().len() + context.server_state_ref().player.playlist.len() } pub fn set_playlist_index(context: &mut AppContext, new_index: usize) { - let playlist_len = context.server_state_ref().player_ref().playlist_ref().len(); + let playlist_len = context.server_state_ref().player.playlist.len(); if playlist_len <= new_index { context .server_state_mut() - .player_mut() - .playlist_mut() + .player + .playlist .set_cursor_index(Some(safe_subtract(playlist_len, 1))); } else { context .server_state_mut() - .player_mut() - .playlist_mut() + .player + .playlist .set_cursor_index(Some(new_index)); } } diff --git a/src/bin/client/commands/goto.rs b/src/bin/client/commands/goto.rs index 02b9033..cf0ec9d 100644 --- a/src/bin/client/commands/goto.rs +++ b/src/bin/client/commands/goto.rs @@ -8,7 +8,7 @@ use crate::config::option::WidgetType; use crate::context::AppContext; fn _directory_goto_playing(context: &mut AppContext) -> DiziResult { - let player_state = context.server_state_ref().player_ref(); + let player_state = &context.server_state_ref().player; if let Some(song) = player_state.song.clone() { let file_path = song.file_path(); @@ -22,7 +22,7 @@ fn _directory_goto_playing(context: &mut AppContext) -> DiziResult { } fn _playlist_goto_playing(context: &mut AppContext) -> DiziResult { - let player_state = context.server_state_ref().player_ref(); + let player_state = &context.server_state_ref().player; match player_state.playlist_status { PlaylistType::DirectoryListing => { diff --git a/src/bin/client/commands/open_file.rs b/src/bin/client/commands/open_file.rs index 7535825..5df7a80 100644 --- a/src/bin/client/commands/open_file.rs +++ b/src/bin/client/commands/open_file.rs @@ -61,8 +61,8 @@ pub fn file_browser_open(context: &mut AppContext) -> DiziResult { pub fn playlist_open(context: &mut AppContext) -> DiziResult { if let Some(index) = context .server_state_ref() - .player_ref() - .playlist_ref() + .player + .playlist .get_cursor_index() { let request = ClientRequest::PlaylistPlay { index: Some(index) }; diff --git a/src/bin/client/commands/search_skim.rs b/src/bin/client/commands/search_skim.rs index b4aea7e..dfae27c 100644 --- a/src/bin/client/commands/search_skim.rs +++ b/src/bin/client/commands/search_skim.rs @@ -49,8 +49,8 @@ fn search_playlist_skim( let items: Vec = context .server_state_ref() - .player_ref() - .playlist_ref() + .player + .playlist .list_ref() .iter() .enumerate() diff --git a/src/bin/client/context/server_state.rs b/src/bin/client/context/server_state.rs index 2b3fe1c..82161fb 100644 --- a/src/bin/client/context/server_state.rs +++ b/src/bin/client/context/server_state.rs @@ -2,7 +2,7 @@ use dizi::player::PlayerState; #[derive(Clone, Debug)] pub struct ServerState { - player: PlayerState, + pub player: PlayerState, } impl ServerState { @@ -11,16 +11,4 @@ impl ServerState { player: PlayerState::new(), } } - - pub fn set_player(&mut self, player: PlayerState) { - self.player = player; - } - - pub fn player_ref(&self) -> &PlayerState { - &self.player - } - - pub fn player_mut(&mut self) -> &mut PlayerState { - &mut self.player - } } diff --git a/src/bin/client/event/process_event.rs b/src/bin/client/event/process_event.rs index 344aa2a..27b7dee 100644 --- a/src/bin/client/event/process_event.rs +++ b/src/bin/client/event/process_event.rs @@ -69,12 +69,12 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { ServerBroadcastEvent::ServerQuery { .. } => {} ServerBroadcastEvent::ServerQueryAll { .. } => {} ServerBroadcastEvent::PlayerState { mut state } => { - if !state.playlist_ref().is_empty() { - let old_state = context.server_state_ref().player_ref(); + if !state.playlist.is_empty() { + let old_state = &context.server_state_ref().player; - let playlist_len = state.playlist_ref().len(); + let playlist_len = state.playlist.len(); let new_cursor_index = old_state - .playlist_ref() + .playlist .get_cursor_index() .map(|s| { if s < playlist_len { @@ -84,19 +84,17 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { } }) .unwrap_or_else(|| 0); - state - .playlist_mut() - .set_cursor_index(Some(new_cursor_index)); + state.playlist.set_cursor_index(Some(new_cursor_index)); } - context.server_state_mut().set_player(state); + context.server_state_mut().player = state; } ServerBroadcastEvent::PlaylistOpen { mut state } => { - if !state.playlist_ref().is_empty() { - let old_state = context.server_state_ref().player_ref(); + if !state.playlist.is_empty() { + let old_state = &context.server_state_ref().player; - let playlist_len = state.playlist_ref().len(); + let playlist_len = state.playlist.len(); let new_cursor_index = old_state - .playlist_ref() + .playlist .get_cursor_index() .map(|s| { if s < playlist_len { @@ -106,47 +104,30 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { } }) .unwrap_or_else(|| 0); - state - .playlist_mut() - .set_cursor_index(Some(new_cursor_index)); + state.playlist.set_cursor_index(Some(new_cursor_index)); } - context.server_state_mut().set_player(state); - let len = context.server_state_ref().player_ref().playlist_ref().len(); + context.server_state_mut().player = state; + let len = context.server_state_ref().player.playlist.len(); context .message_queue_mut() .push_success(format!("Loaded {} songs to playlist", len)); } ServerBroadcastEvent::PlayerFilePlay { file: song } => { - context.server_state_mut().player_mut().set_song(Some(song)); - context - .server_state_mut() - .player_mut() - .set_player_status(PlayerStatus::Playing); - context - .server_state_mut() - .player_mut() - .set_playlist_status(PlaylistType::DirectoryListing); + context.server_state_mut().player.song = Some(song); + context.server_state_mut().player.status = PlayerStatus::Playing; + context.server_state_mut().player.playlist_status = PlaylistType::DirectoryListing; } ServerBroadcastEvent::PlayerPause => { - context - .server_state_mut() - .player_mut() - .set_player_status(PlayerStatus::Paused); + context.server_state_mut().player.status = PlayerStatus::Paused; } ServerBroadcastEvent::PlayerResume => { - context - .server_state_mut() - .player_mut() - .set_player_status(PlayerStatus::Playing); + context.server_state_mut().player.status = PlayerStatus::Playing; } ServerBroadcastEvent::PlayerStop => { - context - .server_state_mut() - .player_mut() - .set_player_status(PlayerStatus::Stopped); + context.server_state_mut().player.status = PlayerStatus::Stopped; } ServerBroadcastEvent::PlayerShuffle { on } => { - context.server_state_mut().player_mut().set_shuffle(on); + context.server_state_mut().player.shuffle = on; let setting = "Shuffle"; let status = if on { "ON" } else { "OFF" }; context @@ -154,7 +135,7 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { .push_success(format!("{} {}", setting, status)); } ServerBroadcastEvent::PlayerRepeat { on } => { - context.server_state_mut().player_mut().set_repeat(on); + context.server_state_mut().player.repeat = on; let setting = "Repeat"; let status = if on { "ON" } else { "OFF" }; context @@ -162,7 +143,7 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { .push_success(format!("{} {}", setting, status)); } ServerBroadcastEvent::PlayerNext { on } => { - context.server_state_mut().player_mut().set_next(on); + context.server_state_mut().player.next = on; let setting = "Next"; let status = if on { "ON" } else { "OFF" }; context @@ -170,13 +151,13 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { .push_success(format!("{} {}", setting, status)); } ServerBroadcastEvent::PlayerVolumeUpdate { volume } => { - context.server_state_mut().player_mut().set_volume(volume); + context.server_state_mut().player.volume = volume; } ServerBroadcastEvent::PlayerProgressUpdate { elapsed } => { - context.server_state_mut().player_mut().set_elapsed(elapsed); + context.server_state_mut().player.elapsed = elapsed; } ServerBroadcastEvent::PlaylistSwapMove { index1, index2 } => { - let playlist = context.server_state_mut().player_mut().playlist_mut(); + let playlist = &mut context.server_state_mut().player.playlist; playlist.list_mut().swap(index1, index2); playlist.set_cursor_index(Some(index2)); if let Some(playing_index) = playlist.get_playing_index() { @@ -189,13 +170,12 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { } } ServerBroadcastEvent::PlaylistClear => { - let playlist = context.server_state_mut().player_mut().playlist_mut(); - let len = playlist.len(); - playlist.clear(); + let playlist_len = context.server_state_mut().player.playlist.len(); + context.server_state_mut().player.playlist.clear(); context.set_view_widget(WidgetType::FileBrowser); context .message_queue_mut() - .push_success(format!("Removed {} songs from playlist", len)); + .push_success(format!("Removed {playlist_len} songs from playlist")); } ServerBroadcastEvent::PlaylistAppend { audio_files } => { let len = audio_files.len(); @@ -205,21 +185,21 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { .collect(); context .server_state_mut() - .player_mut() - .playlist_mut() + .player + .playlist .list_mut() .extend_from_slice(&entries); if context .server_state_ref() - .player_ref() - .playlist_ref() + .player + .playlist .get_cursor_index() .is_none() { context .server_state_mut() - .player_mut() - .playlist_mut() + .player + .playlist .set_cursor_index(Some(0)); } context @@ -227,21 +207,24 @@ pub fn process_server_event(context: &mut AppContext, s: &str) -> DiziResult { .push_success(format!("Added {len} songs to playlist")); } ServerBroadcastEvent::PlaylistRemove { index } => { - let playlist = context.server_state_mut().player_mut().playlist_mut(); - playlist.remove_song(index); + context + .server_state_mut() + .player + .playlist + .remove_song(index); } ServerBroadcastEvent::PlaylistPlay { index } => { - let len = context.server_state_ref().player_ref().playlist_ref().len(); + let len = context.server_state_ref().player.playlist.len(); if index < len { - let player = context.server_state_mut().player_mut(); - player.set_player_status(PlayerStatus::Playing); - player.set_playlist_status(PlaylistType::PlaylistFile); - let cursor_index = player.playlist_ref().get_cursor_index(); - let playing_index = player.playlist_ref().get_playing_index(); + let player = &mut context.server_state_mut().player; + player.status = PlayerStatus::Playing; + player.playlist_status = PlaylistType::PlaylistFile; + let cursor_index = player.playlist.get_cursor_index(); + let playing_index = player.playlist.get_playing_index(); if playing_index == cursor_index { - player.playlist_mut().set_cursor_index(Some(index)); + player.playlist.set_cursor_index(Some(index)); } - player.playlist_mut().set_playing_index(Some(index)); + player.playlist.set_playing_index(Some(index)); } } } diff --git a/src/bin/client/key_command/impl_appexecute.rs b/src/bin/client/key_command/impl_appexecute.rs index ccce024..176731e 100644 --- a/src/bin/client/key_command/impl_appexecute.rs +++ b/src/bin/client/key_command/impl_appexecute.rs @@ -134,7 +134,7 @@ pub fn execute_request( } } ClientRequest::PlaylistPlay { index: None } => { - let playlist = context.server_state_ref().player_ref().playlist_ref(); + let playlist = &context.server_state_ref().player.playlist; if let Some(index) = playlist.get_cursor_index() { let request = ClientRequest::PlaylistPlay { index: Some(index) }; send_client_request(context, &request)?; @@ -144,7 +144,7 @@ pub fn execute_request( if context.get_view_widget() != WidgetType::Playlist { return Ok(()); } - let playlist = context.server_state_ref().player_ref().playlist_ref(); + let playlist = &context.server_state_ref().player.playlist; if let Some(index) = playlist.get_cursor_index() { let request = ClientRequest::PlaylistRemove { index: Some(index) }; send_client_request(context, &request)?; @@ -154,7 +154,7 @@ pub fn execute_request( if context.get_view_widget() != WidgetType::Playlist { return Ok(()); } - let playlist = context.server_state_ref().player_ref().playlist_ref(); + let playlist = &context.server_state_ref().player.playlist; if let Some(index) = playlist.get_cursor_index() { let request = ClientRequest::PlaylistMoveUp { index: Some(index) }; send_client_request(context, &request)?; @@ -164,7 +164,7 @@ pub fn execute_request( if context.get_view_widget() != WidgetType::Playlist { return Ok(()); } - let playlist = context.server_state_ref().player_ref().playlist_ref(); + let playlist = &context.server_state_ref().player.playlist; if let Some(index) = playlist.get_cursor_index() { let request = ClientRequest::PlaylistMoveDown { index: Some(index) }; send_client_request(context, &request)?; diff --git a/src/bin/client/run/run_query.rs b/src/bin/client/run/run_query.rs index 3b919de..0a45d3f 100644 --- a/src/bin/client/run/run_query.rs +++ b/src/bin/client/run/run_query.rs @@ -47,8 +47,8 @@ pub fn run_query(context: &mut AppContext, query: String) -> DiziResult { break; } ServerBroadcastEvent::PlayerState { mut state } => { - if !state.playlist_ref().is_empty() { - state.playlist_mut().set_cursor_index(Some(0)); + if !state.playlist.is_empty() { + state.playlist.set_cursor_index(Some(0)); } let res = state.query(&query)?; println!("{}", res); diff --git a/src/bin/client/run/run_query_all.rs b/src/bin/client/run/run_query_all.rs index 0fa8d13..2cded33 100644 --- a/src/bin/client/run/run_query_all.rs +++ b/src/bin/client/run/run_query_all.rs @@ -49,8 +49,8 @@ pub fn run_query_all(context: &mut AppContext) -> DiziResult { break; } ServerBroadcastEvent::PlayerState { mut state } => { - if !state.playlist_ref().is_empty() { - state.playlist_mut().set_cursor_index(Some(0)); + if !state.playlist.is_empty() { + state.playlist.set_cursor_index(Some(0)); } let mut query_items = state.query_all(); let mut items_sorted: Vec<(String, String)> = query_items.drain().collect(); diff --git a/src/bin/client/ui/views/tui_folder_view.rs b/src/bin/client/ui/views/tui_folder_view.rs index 260faa1..900e787 100644 --- a/src/bin/client/ui/views/tui_folder_view.rs +++ b/src/bin/client/ui/views/tui_folder_view.rs @@ -28,7 +28,7 @@ impl<'a> Widget for TuiFolderView<'a> { let config = self.context.config_ref(); let display_options = config.display_options_ref(); - let currently_playing = self.context.server_state_ref().player_ref().song.as_ref(); + let currently_playing = self.context.server_state_ref().player.song.as_ref(); // render current view if let Some(list) = curr_list.as_ref() { diff --git a/src/bin/client/ui/views/tui_view.rs b/src/bin/client/ui/views/tui_view.rs index 8a8ce44..60d2e0b 100644 --- a/src/bin/client/ui/views/tui_view.rs +++ b/src/bin/client/ui/views/tui_view.rs @@ -60,7 +60,7 @@ impl<'a> Widget for TuiView<'a> { width: area.width, height: 1, }; - TuiFooter::new(self.context.server_state_ref().player_ref()).render(rect, buf); + TuiFooter::new(&self.context.server_state_ref().player).render(rect, buf); } let topbar_width = area.width; @@ -118,11 +118,10 @@ pub fn render_widget( match widget { WidgetType::FileBrowser => TuiFolderView::new(context, focused).render(rect, buf), WidgetType::MusicPlayer => { - TuiPlayer::new(context.server_state_ref().player_ref()).render(rect, buf) + TuiPlayer::new(&context.server_state_ref().player).render(rect, buf) } WidgetType::Playlist => { - TuiPlaylist::new(context.server_state_ref().player_ref(), focused) - .render(rect, buf) + TuiPlaylist::new(&context.server_state_ref().player, focused).render(rect, buf) } } } diff --git a/src/bin/client/ui/widgets/tui_player.rs b/src/bin/client/ui/widgets/tui_player.rs index 53db7f2..d621ed7 100644 --- a/src/bin/client/ui/widgets/tui_player.rs +++ b/src/bin/client/ui/widgets/tui_player.rs @@ -25,7 +25,7 @@ impl<'a> Widget for TuiPlayer<'a> { return; } - let song = self.player.get_song(); + let song = &self.player.song; { let song_name = match song { Some(song) => match song.music_metadata().standard_tags.get("TrackTitle") { @@ -51,12 +51,12 @@ impl<'a> Widget for TuiPlayer<'a> { let on_style = Style::default().fg(Color::Green); let off_style = Style::default().fg(Color::Black); - let playlist_file_style = match self.player.get_playlist_status() { + let playlist_file_style = match self.player.playlist_status { PlaylistType::PlaylistFile => on_style, PlaylistType::DirectoryListing => off_style, }; - let playlist_directory_style = match self.player.get_playlist_status() { + let playlist_directory_style = match self.player.playlist_status { PlaylistType::PlaylistFile => off_style, PlaylistType::DirectoryListing => on_style, }; @@ -66,7 +66,7 @@ impl<'a> Widget for TuiPlayer<'a> { .add_modifier(Modifier::BOLD); let text = Line::from(vec![ Span::styled( - format!("Volume: {}% ", self.player.get_volume(),), + format!("Volume: {}% ", self.player.volume,), player_status_style, ), Span::styled("[PLAYLIST] ", playlist_file_style), @@ -81,7 +81,7 @@ impl<'a> Widget for TuiPlayer<'a> { Paragraph::new(text).render(rect, buf); } - let duration_elapsed = self.player.get_elapsed(); + let duration_elapsed = self.player.elapsed; let duration_played_str = { let total_secs = duration_elapsed.as_secs(); let minutes = total_secs / 60; @@ -90,6 +90,7 @@ impl<'a> Widget for TuiPlayer<'a> { format!("{:02}:{:02}:{:02}", hours, minutes, seconds) }; let total_duration = song + .as_ref() .and_then(|song| song.audio_metadata().total_duration) .unwrap_or(time::Duration::from_secs(0)); let total_duration_str = { @@ -103,20 +104,20 @@ impl<'a> Widget for TuiPlayer<'a> { let on_style = Style::default().fg(Color::Yellow); let off_style = Style::default().fg(Color::Black); - let next_style = match self.player.next_enabled() { + let next_style = match self.player.next { true => on_style, false => off_style, }; - let repeat_style = match self.player.repeat_enabled() { + let repeat_style = match self.player.repeat { true => on_style, false => off_style, }; - let shuffle_style = match self.player.shuffle_enabled() { + let shuffle_style = match self.player.shuffle { true => on_style, false => off_style, }; - let player_status = match self.player.get_player_status() { + let player_status = match self.player.status { PlayerStatus::Playing => "\u{25B6} ", PlayerStatus::Stopped => "\u{2588}\u{2588}", PlayerStatus::Paused => "\u{2590} \u{258C}", diff --git a/src/bin/client/ui/widgets/tui_playlist.rs b/src/bin/client/ui/widgets/tui_playlist.rs index d1419af..addf130 100644 --- a/src/bin/client/ui/widgets/tui_playlist.rs +++ b/src/bin/client/ui/widgets/tui_playlist.rs @@ -31,7 +31,7 @@ impl<'a> TuiPlaylist<'a> { let x = area.left(); let y = area.top(); - let playlist = self.player.playlist_ref(); + let playlist = &self.player.playlist; let drawing_width = area.width as usize; let skip_dist = playlist.first_index_for_viewport(area.height as usize); @@ -62,7 +62,7 @@ impl<'a> TuiPlaylist<'a> { return; } - let playlist = self.player.playlist_ref(); + let playlist = &self.player.playlist; let skip_dist = playlist.first_index_for_viewport(area.height as usize); let curr_index = playlist.get_cursor_index(); @@ -98,8 +98,7 @@ impl<'a> TuiPlaylist<'a> { let x = area.left(); let y = area.top(); - let playlist = self.player.playlist_ref(); - + let playlist = &self.player.playlist; let drawing_width = area.width as usize; let skip_dist = playlist.first_index_for_viewport(area.height as usize); diff --git a/src/bin/server/audio/symphonia/decode.rs b/src/bin/server/audio/symphonia/decode.rs index ca2107e..2167e95 100644 --- a/src/bin/server/audio/symphonia/decode.rs +++ b/src/bin/server/audio/symphonia/decode.rs @@ -183,7 +183,7 @@ where process_message(msg); } - // if sample_offset is greater than samples_count, then we've reached the end + // if sample_offsetcurrent_volume is greater than samples_count, then we've reached the end let sample_offset = { *frame_index.read().unwrap() }; if sample_offset >= samples_count { if let Some(stream_tx) = stream_tx.take() { diff --git a/src/bin/server/audio/symphonia/player/impl_audio_player.rs b/src/bin/server/audio/symphonia/player/impl_audio_player.rs index 68b162f..0d41768 100644 --- a/src/bin/server/audio/symphonia/player/impl_audio_player.rs +++ b/src/bin/server/audio/symphonia/player/impl_audio_player.rs @@ -208,9 +208,6 @@ impl AudioPlayer for SymphoniaPlayer { } } - fn get_elapsed(&self) -> time::Duration { - self.state.elapsed - } fn set_elapsed(&mut self, elapsed: time::Duration) { self.state.elapsed = elapsed; } diff --git a/src/bin/server/audio/symphonia/player/mod.rs b/src/bin/server/audio/symphonia/player/mod.rs index 5b92bc0..a48a373 100644 --- a/src/bin/server/audio/symphonia/player/mod.rs +++ b/src/bin/server/audio/symphonia/player/mod.rs @@ -6,7 +6,7 @@ use std::thread::{self, JoinHandle}; use cpal::traits::HostTrait; -use dizi::error::DiziResult; +use dizi::error::{DiziError, DiziErrorKind, DiziResult}; use dizi::player::{PlayerState, PlayerStatus}; use dizi::song::DiziAudioFile; @@ -32,7 +32,11 @@ pub struct SymphoniaPlayer { impl SymphoniaPlayer { pub fn new(config_t: &config::AppConfig, event_tx: ServerEventSender) -> DiziResult { let audio_host = get_default_host(config_t.server_ref().audio_system); - let audio_device = audio_host.default_output_device().unwrap(); + let audio_device = audio_host.default_output_device().ok_or_else(|| { + let error_msg = "Failed to get default output device"; + tracing::error!("{error_msg}"); + DiziError::new(DiziErrorKind::Symphonia, error_msg.to_string()) + })?; let (player_req_tx, player_req_rx) = mpsc::channel(); let (player_res_tx, player_res_rx) = mpsc::channel(); diff --git a/src/bin/server/audio/symphonia/stream.rs b/src/bin/server/audio/symphonia/stream.rs index 65913d6..af6c237 100644 --- a/src/bin/server/audio/symphonia/stream.rs +++ b/src/bin/server/audio/symphonia/stream.rs @@ -35,7 +35,7 @@ pub enum PlayerStreamEvent { pub struct PlayerStreamEventListener { pub stream_tx: mpsc::Sender, pub player_res_tx: mpsc::Sender, - pub event_tx: mpsc::Sender, + pub _event_tx: mpsc::Sender, pub event_rx: mpsc::Receiver, } @@ -71,7 +71,7 @@ impl PlayerStreamEventListener { Self { stream_tx, player_res_tx, - event_tx, + _event_tx: event_tx, event_rx, } } @@ -247,177 +247,179 @@ impl PlayerStream { .format .tracks() .iter() - .find(|t| t.codec_params.codec != CODEC_TYPE_NULL); - - match track { - None => Err(DiziError::new(DiziErrorKind::NoDevice, "".to_string())), - Some(track) => { - // Store the track identifier, it will be used to filter packets. - let track_id = track.id; - - tracing::debug!("track: {:#?}", track); - - // Use the default options for the decoder. - let dec_opts: DecoderOptions = Default::default(); - - // Create a decoder for the track. - let decoder = - symphonia::default::get_codecs().make(&track.codec_params, &dec_opts)?; - - let config = self.device.default_output_config().unwrap(); - - let audio_config = cpal::StreamConfig { - channels: track - .codec_params - .channels - .map(|c| c.count() as u16) - .unwrap_or(2u16), - sample_rate: cpal::SampleRate( - track - .codec_params - .sample_rate - .unwrap_or_else(|| config.sample_rate().0), - ), - buffer_size: cpal::BufferSize::Default, - }; + .find(|t| t.codec_params.codec != CODEC_TYPE_NULL) + .ok_or_else(|| { + let error_msg = "No tracks found"; + tracing::error!("{error_msg}"); + DiziError::new(DiziErrorKind::Server, error_msg.to_string()) + })?; + // Store the track identifier, it will be used to filter packets. + let track_id = track.id; + + tracing::debug!("track: {:#?}", track); + + // Use the default options for the decoder. + let dec_opts: DecoderOptions = Default::default(); + + // Create a decoder for the track. + let decoder = symphonia::default::get_codecs().make(&track.codec_params, &dec_opts)?; + + let config = self.device.default_output_config().map_err(|err| { + let error_msg = "Failed to get default output config"; + tracing::error!("{error_msg}: {err}"); + DiziError::new(DiziErrorKind::Symphonia, error_msg.to_string()) + })?; + + let audio_config = cpal::StreamConfig { + channels: track + .codec_params + .channels + .map(|c| c.count() as u16) + .unwrap_or(2u16), + sample_rate: cpal::SampleRate( + track + .codec_params + .sample_rate + .unwrap_or_else(|| config.sample_rate().0), + ), + buffer_size: cpal::BufferSize::Default, + }; - tracing::debug!("audio_config: {:#?}", audio_config); - - let stream_tx = self.event_poller.stream_tx.clone(); - - let packet_reader = PacketReader::new(probed.format, track_id); - let mut packet_decoder = PacketDecoder::new(decoder); - - match config.sample_format() { - cpal::SampleFormat::U8 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| ((packet as f32) * volume) as u8, - )?; - Ok(res) - } - cpal::SampleFormat::U16 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| ((packet as f32) * volume) as u16, - )?; - Ok(res) - } - cpal::SampleFormat::U32 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| ((packet as f32) * volume) as u32, - )?; - Ok(res) - } - cpal::SampleFormat::I8 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| ((packet as f32) * volume) as i8, - )?; - Ok(res) - } - cpal::SampleFormat::I16 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| ((packet as f32) * volume) as i16, - )?; - Ok(res) - } - cpal::SampleFormat::I32 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| ((packet as f32) * volume) as i32, - )?; - Ok(res) - } - cpal::SampleFormat::F32 => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| packet * volume, - )?; - Ok(res) - } - _ => { - let mut samples = Vec::new(); - for packet in packet_reader { - let packet_sample = packet_decoder.decode::(packet)?; - samples.extend(packet_sample); - } - let res = stream_loop::( - stream_tx, - &self.device, - &audio_config, - samples, - volume, - |packet, volume| (packet * volume as f64) as f64, - )?; - Ok(res) - } + tracing::debug!("audio_config: {:#?}", audio_config); + + let stream_tx = self.event_poller.stream_tx.clone(); + + let packet_reader = PacketReader::new(probed.format, track_id); + let mut packet_decoder = PacketDecoder::new(decoder); + + match config.sample_format() { + cpal::SampleFormat::U8 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| ((packet as f32) * volume) as u8, + )?; + Ok(res) + } + cpal::SampleFormat::U16 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| ((packet as f32) * volume) as u16, + )?; + Ok(res) + } + cpal::SampleFormat::U32 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| ((packet as f32) * volume) as u32, + )?; + Ok(res) + } + cpal::SampleFormat::I8 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| ((packet as f32) * volume) as i8, + )?; + Ok(res) + } + cpal::SampleFormat::I16 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| ((packet as f32) * volume) as i16, + )?; + Ok(res) + } + cpal::SampleFormat::I32 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| ((packet as f32) * volume) as i32, + )?; + Ok(res) + } + cpal::SampleFormat::F32 => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); + } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| packet * volume, + )?; + Ok(res) + } + _ => { + let mut samples = Vec::new(); + for packet in packet_reader { + let packet_sample = packet_decoder.decode::(packet)?; + samples.extend(packet_sample); } + let res = stream_loop::( + stream_tx, + &self.device, + &audio_config, + samples, + volume, + |packet, volume| (packet * volume as f64) as f64, + )?; + Ok(res) } } } diff --git a/src/bin/server/traits/audio_player.rs b/src/bin/server/traits/audio_player.rs index ada06fd..ac5fa62 100644 --- a/src/bin/server/traits/audio_player.rs +++ b/src/bin/server/traits/audio_player.rs @@ -36,7 +36,6 @@ pub trait AudioPlayer { fn set_repeat(&mut self, repeat: bool); fn set_shuffle(&mut self, shuffle: bool); - fn get_elapsed(&self) -> time::Duration; fn set_elapsed(&mut self, elapsed: time::Duration); fn current_song_ref(&self) -> Option<&DiziAudioFile>; diff --git a/src/error/error_kind.rs b/src/error/error_kind.rs index 22d82f8..c003bb3 100644 --- a/src/error/error_kind.rs +++ b/src/error/error_kind.rs @@ -4,6 +4,8 @@ use std::io; #[derive(Debug)] pub enum DiziErrorKind { Server, + Symphonia, + // io related IoError(io::ErrorKind), @@ -21,8 +23,6 @@ pub enum DiziErrorKind { SendError, ReceiveError, - SymphoniaError(symphonia::core::errors::Error), - CpalBuildStreamError(cpal::BuildStreamError), CpalPlayStreamError(cpal::PlayStreamError), CpalPauseStreamError(cpal::PauseStreamError), @@ -66,8 +66,8 @@ impl From for DiziErrorKind { } impl From for DiziErrorKind { - fn from(e: symphonia::core::errors::Error) -> Self { - Self::SymphoniaError(e) + fn from(_: symphonia::core::errors::Error) -> Self { + Self::Symphonia } } diff --git a/src/player.rs b/src/player.rs index bbb466a..bd5bea0 100644 --- a/src/player.rs +++ b/src/player.rs @@ -51,68 +51,6 @@ impl PlayerState { Self::default() } - pub fn get_song(&self) -> Option<&DiziAudioFile> { - self.song.as_ref() - } - pub fn set_song(&mut self, song: Option) { - self.song = song; - } - - pub fn get_elapsed(&self) -> time::Duration { - self.elapsed - } - pub fn set_elapsed(&mut self, elapsed: time::Duration) { - self.elapsed = elapsed; - } - - pub fn get_player_status(&self) -> PlayerStatus { - self.status - } - pub fn set_player_status(&mut self, status: PlayerStatus) { - self.status = status; - } - pub fn get_playlist_status(&self) -> PlaylistType { - self.playlist_status - } - pub fn set_playlist_status(&mut self, status: PlaylistType) { - self.playlist_status = status; - } - - pub fn get_volume(&self) -> usize { - self.volume - } - pub fn set_volume(&mut self, volume: usize) { - self.volume = volume; - } - - pub fn repeat_enabled(&self) -> bool { - self.repeat - } - pub fn set_repeat(&mut self, repeat: bool) { - self.repeat = repeat; - } - - pub fn shuffle_enabled(&self) -> bool { - self.shuffle - } - pub fn set_shuffle(&mut self, shuffle: bool) { - self.shuffle = shuffle; - } - - pub fn next_enabled(&self) -> bool { - self.next - } - pub fn set_next(&mut self, next: bool) { - self.next = next; - } - - pub fn playlist_ref(&self) -> &FilePlaylist { - &self.playlist - } - pub fn playlist_mut(&mut self) -> &mut FilePlaylist { - &mut self.playlist - } - pub fn query(&self, query: &str) -> DiziResult { let vars = self.query_all(); @@ -132,44 +70,38 @@ impl PlayerState { pub fn query_all(&self) -> HashMap { let mut vars = HashMap::new(); Self::load_player_query_vars(&mut vars, self); - if let Some(song) = self.get_song() { + if let Some(song) = self.song.as_ref() { Self::load_song_query_vars(&mut vars, song); } vars } fn load_player_query_vars(vars: &mut HashMap, player_state: &PlayerState) { - vars.insert( - "player.status".to_string(), - player_state.get_player_status().to_string(), - ); + vars.insert("player.status".to_string(), player_state.status.to_string()); vars.insert( "player.volume".to_string(), - format!("{}", player_state.get_volume()), - ); - vars.insert( - "player.next".to_string(), - format!("{}", player_state.next_enabled()), + format!("{}", player_state.volume), ); + vars.insert("player.next".to_string(), format!("{}", player_state.next)); vars.insert( "player.repeat".to_string(), - format!("{}", player_state.repeat_enabled()), + format!("{}", player_state.repeat), ); vars.insert( "player.shuffle".to_string(), - format!("{}", player_state.shuffle_enabled()), + format!("{}", player_state.shuffle), ); vars.insert( "playlist.status".to_string(), - player_state.get_playlist_status().to_string(), + player_state.playlist_status.to_string(), ); - if let Some(index) = player_state.playlist_ref().get_playing_index() { + if let Some(index) = player_state.playlist.get_playing_index() { vars.insert("playlist.index".to_string(), format!("{}", index)); } vars.insert( "playlist.length".to_string(), - format!("{}", player_state.playlist_ref().len()), + format!("{}", player_state.playlist.len()), ); vars.insert("audio.host".to_string(), player_state.audio_host.clone()); } diff --git a/src/song.rs b/src/song.rs index c1cbc11..3e47588 100644 --- a/src/song.rs +++ b/src/song.rs @@ -51,7 +51,7 @@ impl DiziFile { let file_name = path .file_name() .map(|s| s.to_string_lossy()) - .unwrap() + .unwrap_or_default() .into_owned(); Self { file_name,