diff --git a/src/audio/backend.rs b/src/audio/backend.rs index 236807d..5e11561 100644 --- a/src/audio/backend.rs +++ b/src/audio/backend.rs @@ -1,32 +1,52 @@ -use librespot::playback::audio_backend::{Sink, SinkAsBytes, SinkResult}; +use librespot::playback::audio_backend::{Sink, SinkAsBytes, SinkError, SinkResult}; use librespot::playback::convert::Converter; use librespot::playback::decoder::AudioPacket; -use std::io::Write; +use log::error; +use std::io::{Stdout, Write}; use crate::ipc; use crate::ipc::packet::IpcPacket; pub struct StdoutSink { client: ipc::Client, + output: Option>, } impl StdoutSink { pub fn new(client: ipc::Client) -> Self { - StdoutSink { client } + StdoutSink { + client, + output: None, + } } } impl Sink for StdoutSink { fn start(&mut self) -> SinkResult<()> { - // TODO: Handle error - self.client.send(IpcPacket::StartPlayback).unwrap(); + if let Err(why) = self.client.send(IpcPacket::StartPlayback) { + error!("Failed to send start playback packet: {}", why); + return Err(SinkError::ConnectionRefused(why.to_string())); + } + + self.output.get_or_insert(Box::new(std::io::stdout())); Ok(()) } fn stop(&mut self) -> SinkResult<()> { - // Stop songbird's playback - self.client.send(IpcPacket::StopPlayback).unwrap(); + if let Err(why) = self.client.send(IpcPacket::StopPlayback) { + error!("Failed to send stop playback packet: {}", why); + return Err(SinkError::ConnectionRefused(why.to_string())); + } + + self + .output + .take() + .ok_or(SinkError::NotConnected( + "StdoutSink is not connected".to_string(), + ))? + .flush() + .map_err(|why| SinkError::OnWrite(why.to_string()))?; Ok(()) } @@ -58,7 +78,14 @@ impl Sink for StdoutSink { impl SinkAsBytes for StdoutSink { fn write_bytes(&mut self, data: &[u8]) -> SinkResult<()> { - std::io::stdout().write_all(data).unwrap(); + self + .output + .as_deref_mut() + .ok_or(SinkError::NotConnected( + "StdoutSink is not connected".to_string(), + ))? + .write_all(data) + .map_err(|why| SinkError::OnWrite(why.to_string()))?; Ok(()) } diff --git a/src/bot/commands/music/playing.rs b/src/bot/commands/music/playing.rs index 87fa68e..1abd137 100644 --- a/src/bot/commands/music/playing.rs +++ b/src/bot/commands/music/playing.rs @@ -118,7 +118,6 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu Some(user) => user, None => { // This shouldn't happen - // TODO: Test if this can no longer happen error!("Could not find user with id {}", owner); diff --git a/src/bot/mod.rs b/src/bot/mod.rs index ae78b1f..2bddc4f 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -1,3 +1,2 @@ -// TODO: Check all image urls in embed responses pub mod commands; pub mod events; diff --git a/src/session/mod.rs b/src/session/mod.rs index 89bb03f..2889c24 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -246,8 +246,8 @@ impl SpoticordSession { let mut instance = ipc_instance.clone(); let context = ipc_context.clone(); - // TODO: Check if this is actually needed - // The new backend may have fixed the need for this + // Fetch track info + // This is done in a separate task to avoid blocking the IPC handler tokio::spawn(async move { if let Err(why) = instance.update_track(&context, &owner_id, track_id).await { error!("Failed to update track: {:?}", why);