обновление

This commit is contained in:
2026-10-13 16:24:18 +02:00
parent f1c5deb4bc
commit 255a99ed0f
7 changed files with 491 additions and 158 deletions

81
src/audio.rs Normal file
View File

@@ -0,0 +1,81 @@
use std::fs::File;
use std::io::BufReader;
use std::path::PathBuf;
use std::time::Duration;
use rodio::{Decoder, OutputStream, OutputStreamBuilder, Sink};
pub struct AudioPlayer {
_stream: OutputStream,
sink: Sink,
paused_pos: Option<Duration>,
}
impl AudioPlayer {
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
let stream_handle = OutputStreamBuilder::open_default_stream()?;
let sink = Sink::connect_new(&stream_handle.mixer());
sink.set_volume(1.0);
Ok(Self { _stream: stream_handle, sink, paused_pos: None })
}
pub fn play(&mut self, path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
self.sink.stop();
self.paused_pos = None;
let file = BufReader::new(File::open(path)?);
let source = Decoder::new(file)?;
self.sink.append(source);
self.sink.play();
Ok(())
}
pub fn position(&self) -> Duration {
if self.sink.is_paused() {
self.paused_pos.unwrap_or_else(|| self.sink.get_pos())
} else {
self.sink.get_pos()
}
}
pub fn toggle_pause(&mut self) {
if self.sink.is_paused() {
self.sink.play();
self.paused_pos = None;
} else {
self.paused_pos = Some(self.sink.get_pos());
self.sink.pause();
}
}
pub fn stop(&mut self) {
self.sink.stop();
self.paused_pos = None;
}
pub fn is_finished(&self) -> bool {
self.sink.empty()
}
pub fn volume(&self) -> f32 {
self.sink.volume()
}
pub fn change_volume(&mut self, delta: f32) {
let v = (self.sink.volume() + delta).clamp(0.0, 2.0);
self.sink.set_volume(v);
}
pub fn seek_by(&mut self, delta: i64, total: Duration) -> Result<Duration, Box<dyn std::error::Error>> {
let current = self.position();
let new_secs = (current.as_secs() as i64 + delta).max(0) as u64;
let mut new_pos = Duration::from_secs(new_secs);
if !total.is_zero() && new_pos >= total {
new_pos = total.saturating_sub(Duration::from_millis(100));
}
self.sink.try_seek(new_pos)?;
if self.sink.is_paused() {
self.paused_pos = Some(new_pos);
}
Ok(new_pos)
}
}