80 lines
2.1 KiB
Rust
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(),
|
|
}
|
|
}
|
|
}
|