use rodio::{Decoder, OutputStream, Sink};
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
pub struct AudioPlayer {
_stream: OutputStream,
sink: Sink,
}
impl AudioPlayer {
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
let (stream, stream_handle) = OutputStream::try_default()?;
let sink = Sink::try_new(&stream_handle)?;
Ok(AudioPlayer {
_stream: stream,
sink,
})
}
pub fn play_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<dyn std::error::Error>> {
let file = File::open(path.as_ref())?;
let source = Decoder::new(BufReader::new(file))?;
self.sink.append(source);
Ok(())
}
pub fn play_file_blocking<P: AsRef<Path>>(
&self,
path: P,
) -> Result<(), Box<dyn std::error::Error>> {
self.play_file(path)?;
self.sink.sleep_until_end();
Ok(())
}
#[allow(dead_code)]
pub fn is_playing(&self) -> bool {
!self.sink.empty()
}
#[allow(dead_code)]
pub fn pause(&self) {
self.sink.pause();
}
#[allow(dead_code)]
pub fn resume(&self) {
self.sink.play();
}
#[allow(dead_code)]
pub fn stop(&self) {
self.sink.stop();
}
#[allow(dead_code)]
pub fn set_volume(&self, volume: f32) {
self.sink.set_volume(volume);
}
#[allow(dead_code)]
pub fn volume(&self) -> f32 {
self.sink.volume()
}
}
pub fn play_wav_file<P: AsRef<Path>>(path: P) -> Result<(), Box<dyn std::error::Error>> {
let player = AudioPlayer::new()?;
player.play_file_blocking(&path)?;
Ok(())
}
#[allow(dead_code)]
pub fn play_wav_with_message<P: AsRef<Path>>(
path: P,
message: &str,
) -> Result<(), Box<dyn std::error::Error>> {
println!("{}", message);
play_wav_file(path)
}