Add audio.rs for audio playback
This commit is contained in:
84
src/player/audio.rs
Normal file
84
src/player/audio.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
//! 音頻播放模組
|
||||
|
||||
use anyhow::Result;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::io::Write;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AudioPlayer {
|
||||
process: Option<std::process::Child>,
|
||||
volume: f32,
|
||||
muted: bool,
|
||||
}
|
||||
|
||||
impl AudioPlayer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
process: None,
|
||||
volume: 1.0,
|
||||
muted: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play(&mut self, path: &str, start_ms: u64) -> Result<()> {
|
||||
self.stop()?;
|
||||
|
||||
let start_sec = start_ms as f64 / 1000.0;
|
||||
let volume_filter = if self.muted {
|
||||
"volume=0".to_string()
|
||||
} else {
|
||||
format!("volume={}", self.volume)
|
||||
};
|
||||
|
||||
let mut cmd = Command::new("ffplay");
|
||||
cmd.args([
|
||||
"-nodisp",
|
||||
"-autoexit",
|
||||
"-ss", &format!("{}", start_sec),
|
||||
"-af", &volume_filter,
|
||||
"-i", path,
|
||||
])
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.spawn()?;
|
||||
|
||||
self.process = Some(cmd);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn stop(&mut self) -> Result<()> {
|
||||
if let Some(mut child) = self.process.take() {
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_volume(&mut self, volume: f32) {
|
||||
self.volume = volume.clamp(0.0, 1.0);
|
||||
if !self.muted {
|
||||
self.restart_with_volume()?;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_mute(&mut self) -> bool {
|
||||
self.muted = !self.muted;
|
||||
self.muted
|
||||
}
|
||||
|
||||
pub fn is_muted(&self) -> bool {
|
||||
self.muted
|
||||
}
|
||||
|
||||
fn restart_with_volume(&mut self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AudioPlayer {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.stop();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user