Actually usable????????//

This commit is contained in:
2024-11-21 05:02:30 +02:00
parent b1c8417b0f
commit 4ee4ca1add
26 changed files with 2339 additions and 356 deletions

View File

@@ -7,4 +7,7 @@ license.workspace = true
authors.workspace = true
[dependencies]
rodio = { version = "0.20.1", features = ["symphonia-all"] }
rodio.workspace = true
lazy_static.workspace = true
anyhow.workspace = true
log.workspace = true

View File

@@ -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);
}
}