Actually usable????????//
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
use std::{path::Path, time::Duration};
|
||||
|
||||
use rodio::{Decoder, OutputStream, OutputStreamHandle, Sink, Source};
|
||||
|
||||
type Result<T> = anyhow::Result<T>;
|
||||
|
||||
pub struct Player {
|
||||
_stream: OutputStream,
|
||||
_stream_handle: OutputStreamHandle,
|
||||
sink: Sink,
|
||||
source_len: Duration,
|
||||
tested_for_song_end: bool,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub fn new() -> Self {
|
||||
let (_stream, _stream_handle) = OutputStream::try_default().unwrap();
|
||||
let sink = Sink::try_new(&_stream_handle).unwrap();
|
||||
sink.pause();
|
||||
Self {
|
||||
_stream,
|
||||
_stream_handle,
|
||||
sink,
|
||||
source_len: Default::default(),
|
||||
tested_for_song_end: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn play_song(&mut self, path: &Path) -> Result<()> {
|
||||
let file = std::io::BufReader::new(std::fs::File::open(path)?);
|
||||
let source = Decoder::new(file)?;
|
||||
self.tested_for_song_end = false;
|
||||
self.source_len = source.total_duration().unwrap();
|
||||
self.sink.clear();
|
||||
self.sink.append(source);
|
||||
self.sink.play();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_played_f(&self) -> f64 {
|
||||
let source_len = self.source_len.as_millis();
|
||||
let curr_len = self.sink.get_pos().as_millis();
|
||||
if source_len == 0 || curr_len == 0 {
|
||||
return 0.0;
|
||||
}
|
||||
curr_len as f64 / source_len as f64
|
||||
}
|
||||
|
||||
pub fn get_played_len(&self) -> Duration {
|
||||
self.sink.get_pos()
|
||||
}
|
||||
|
||||
pub fn get_ms_left(&self) -> u64 {
|
||||
let source_len = self.source_len.as_millis();
|
||||
let curr_len = self.sink.get_pos().as_millis();
|
||||
if source_len < curr_len {
|
||||
return 0;
|
||||
}
|
||||
(source_len - curr_len) as u64
|
||||
}
|
||||
|
||||
pub fn just_stopped(&mut self) -> bool {
|
||||
if self.sink.len() == 0 && !self.tested_for_song_end {
|
||||
self.tested_for_song_end = true;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play(&self) {
|
||||
self.sink.play()
|
||||
}
|
||||
|
||||
pub fn pause(&self) {
|
||||
self.sink.pause()
|
||||
}
|
||||
|
||||
pub fn seek_to_f(&self, f: f64) -> Result<()> {
|
||||
let dur = self.source_len.as_millis() as f64 * f.clamp(0.0, 1.0);
|
||||
self.seek(Duration::from_millis(dur as u64))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn seek(&self, d: Duration) -> Result<()> {
|
||||
if let Err(e) = self.sink.try_seek(d) {
|
||||
anyhow::bail!("{e:?}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_paused(&self) -> bool {
|
||||
self.sink.is_paused()
|
||||
}
|
||||
|
||||
pub fn set_volume(&self, vol: f64) {
|
||||
// clamped for the safety of my, and your ears
|
||||
self.sink.set_volume(vol.clamp(0.0, 1.0) as f32);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user