0

I am trying to use rodio crate in my project for providing audio playback feature. I created this API so far,

use rodio::{Decoder, OutputStream, OutputStreamHandle, PlayError, Sink, StreamError};
use std::{
    fs::File,
    io::BufReader,
    sync::{Arc, Mutex},
    thread,
};

pub struct Playback {
    sink: Arc<Mutex<Sink>>,
    stream_handle: OutputStreamHandle,
    is_playing: bool,
}

#[derive(Debug)]
pub enum PlaybackError {
    StreamCreationError(StreamError),
    SinkCreationError(PlayError),
}

impl Playback {
    pub fn new() -> Result<Self, PlaybackError> {
        let (_stream, stream_handle) = match OutputStream::try_default() {
            Ok(s) => s,
            Err(e) => {
                log::error!("Error! Failed to create output stream. {}", e);
                return Err(PlaybackError::StreamCreationError(e));
            }
        };

        let sink = match Sink::try_new(&stream_handle) {
            Ok(s) => s,
            Err(e) => {
                log::error!("Error! Could not create sink. {}", e);
                return Err(PlaybackError::SinkCreationError(e));
            }
        };

        Ok(Self {
            sink: Arc::new(Mutex::new(sink)),
            stream_handle,
            is_playing: false,
        })
    }

    pub fn play(&self, filepath: String) {
        log::info!("Playing {}..", filepath);

        let file = match File::open(&filepath) {
            Ok(f) => f,
            Err(e) => {
                log::error!("Error! Could not open file {}. {}", &filepath, e);
                return;
            }
        };

        let buf_reader = BufReader::new(file);

        let source = match Decoder::new(buf_reader) {
            Ok(s) => s,
            Err(e) => {
                log::error!("Error! Could not create decoder. {}", e);
                return;
            }
        };

        let sink = self.sink.lock().unwrap();

        sink.append(source);

        let sink_clone = Arc::clone(&self.sink);

        let thread = thread::spawn(move || {
            let sink = sink_clone.lock().unwrap();

            sink.sleep_until_end();

            // thread::sleep(Duration::from_secs(2));
        });

        thread.join().unwrap();
    }
}

I am not getting any errors, but I can't hear anything either. If I however move all the code from new() to play() it works and I can hear the audio output.

What am I doing wrong here?

apoorv569
  • 143
  • 1
  • 12

0 Answers0