rmp/src/playback.rs

80 lines
2.1 KiB
Rust

use std::{fs::File, path::PathBuf};
use rodio::{OutputStream, OutputStreamHandle, Sink};
use super::decoder::{Decoder, DecoderImpl, SourceWrapper};
pub struct Playback {
/// These must not be dropped before the sink
_stream: OutputStream,
_stream_handle: OutputStreamHandle,
sink: Sink,
}
pub enum PlaybackState {
Empty,
Playing,
Paused,
}
impl Playback {
pub fn new() -> Self {
let (_stream, _stream_handle) = OutputStream::try_default().unwrap();
let sink: Sink = Sink::try_new(&_stream_handle).unwrap();
Self {
_stream,
_stream_handle,
sink,
}
}
pub fn get_state(&self) -> PlaybackState {
// TODO: We know if it's playing but not what is playing. Figure it out later
if self.sink.empty() {
return PlaybackState::Empty;
}
match self.sink.is_paused() {
true => PlaybackState::Paused,
false => PlaybackState::Playing,
}
}
/// Clear the queue and start playback immediately.
pub fn play_immediate(&mut self, path: PathBuf) {
let mut source: Option<Box<dyn DecoderImpl<Item = i16>>> = None;
{
let file = File::open(&path).unwrap();
if let Ok(decoder) = Decoder::rodio(SourceWrapper::from_file(file)) {
source = Some(decoder);
};
}
if source.is_none() {
let file = File::open(&path).unwrap();
if let Ok(decoder) = Decoder::custom(SourceWrapper::from_file(file)) {
source = Some(decoder);
}
}
match source {
Some(source) => {
self.sink.clear();
self.sink.append(source);
self.sink.play();
}
None => eprintln!("No handler found for '{path:?}'"),
}
}
/// Toggle playback pause if possible.
pub fn toggle_pause(&mut self) {
match self.get_state() {
PlaybackState::Empty => (),
PlaybackState::Playing => self.sink.pause(),
PlaybackState::Paused => self.sink.play(),
}
}
}