feat(player): add audio playback with ffplay
This commit is contained in:
99
src/main.rs
99
src/main.rs
@@ -16,6 +16,7 @@ mod web;
|
||||
|
||||
use config::Config;
|
||||
use overlay::{AsrLoader, ChunkLoader, YoloLoader};
|
||||
use player::audio::AudioPlayer;
|
||||
use player::ffmpeg::FFmpegDecoder;
|
||||
use player::state::{PlaybackState, PlayerState};
|
||||
|
||||
@@ -64,6 +65,7 @@ fn run(config: &Config) -> Result<()> {
|
||||
let mut asr: Option<AsrLoader> = None;
|
||||
let mut yolo: Option<YoloLoader> = None;
|
||||
let mut chunks: Option<ChunkLoader> = None;
|
||||
let mut audio_player: Option<AudioPlayer> = None;
|
||||
let mut is_fullscreen = false;
|
||||
let mut is_dragging = false;
|
||||
|
||||
@@ -85,6 +87,10 @@ fn run(config: &Config) -> Result<()> {
|
||||
texture = Some(tex);
|
||||
dec.start_decoding(0)?;
|
||||
decoder = Some(dec);
|
||||
|
||||
let player = AudioPlayer::new();
|
||||
info!("Audio player initialized");
|
||||
audio_player = Some(player);
|
||||
}
|
||||
|
||||
if let Some(ref asr_path) = config.asr {
|
||||
@@ -158,12 +164,21 @@ fn run(config: &Config) -> Result<()> {
|
||||
match key {
|
||||
sdl2::keyboard::Keycode::Escape => running = false,
|
||||
sdl2::keyboard::Keycode::Space => {
|
||||
player_state.playback =
|
||||
let was_playing = player_state.playback == PlaybackState::Playing;
|
||||
player_state.playback = if was_playing {
|
||||
PlaybackState::Paused
|
||||
} else {
|
||||
PlaybackState::Playing
|
||||
};
|
||||
if let Some(ref mut audio) = audio_player {
|
||||
if player_state.playback == PlaybackState::Playing {
|
||||
PlaybackState::Paused
|
||||
if !player_state.muted {
|
||||
audio.resume();
|
||||
}
|
||||
} else {
|
||||
PlaybackState::Playing
|
||||
};
|
||||
audio.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
sdl2::keyboard::Keycode::S => {
|
||||
player_state.show_subtitle = !player_state.show_subtitle;
|
||||
@@ -188,6 +203,14 @@ fn run(config: &Config) -> Result<()> {
|
||||
}
|
||||
sdl2::keyboard::Keycode::M => {
|
||||
player_state.muted = !player_state.muted;
|
||||
if let Some(ref mut audio) = audio_player {
|
||||
if player_state.muted {
|
||||
audio.pause();
|
||||
} else if player_state.playback == PlaybackState::Playing {
|
||||
audio.resume();
|
||||
}
|
||||
}
|
||||
info!("Audio: {}", if player_state.muted { "MUTED" } else { "ON" });
|
||||
}
|
||||
sdl2::keyboard::Keycode::F => {
|
||||
is_fullscreen = !is_fullscreen;
|
||||
@@ -197,39 +220,62 @@ fn run(config: &Config) -> Result<()> {
|
||||
dec.seek(0).ok();
|
||||
player_state.current_frame = 0;
|
||||
player_state.current_time_ms = 0;
|
||||
sync_audio(
|
||||
&mut audio_player,
|
||||
&config.video,
|
||||
0,
|
||||
player_state.playback == PlaybackState::Playing,
|
||||
);
|
||||
}
|
||||
}
|
||||
sdl2::keyboard::Keycode::End => {
|
||||
if let Some(ref mut dec) = decoder {
|
||||
let last_frame = player_state.total_frames.saturating_sub(1);
|
||||
dec.seek(
|
||||
((last_frame as f64 / player_state.fps) * 1000.0) as u64,
|
||||
)
|
||||
.ok();
|
||||
let time_ms =
|
||||
((last_frame as f64 / player_state.fps) * 1000.0) as u64;
|
||||
dec.seek(time_ms).ok();
|
||||
player_state.current_frame = last_frame;
|
||||
player_state.current_time_ms = player_state.duration_ms;
|
||||
sync_audio(
|
||||
&mut audio_player,
|
||||
&config.video,
|
||||
time_ms,
|
||||
player_state.playback == PlaybackState::Playing,
|
||||
);
|
||||
}
|
||||
}
|
||||
sdl2::keyboard::Keycode::Left => {
|
||||
let step = if shift { 60 } else { 1 };
|
||||
if let Some(ref mut dec) = decoder {
|
||||
let current = player_state.current_frame.saturating_sub(step);
|
||||
dec.seek(((current as f64 / player_state.fps) * 1000.0) as u64)
|
||||
.ok();
|
||||
player_state.current_frame = current;
|
||||
player_state.current_time_ms =
|
||||
let time_ms =
|
||||
((current as f64 / player_state.fps) * 1000.0) as u64;
|
||||
dec.seek(time_ms).ok();
|
||||
player_state.current_frame = current;
|
||||
player_state.current_time_ms = time_ms;
|
||||
sync_audio(
|
||||
&mut audio_player,
|
||||
&config.video,
|
||||
time_ms,
|
||||
player_state.playback == PlaybackState::Playing,
|
||||
);
|
||||
}
|
||||
}
|
||||
sdl2::keyboard::Keycode::Right => {
|
||||
let step = if shift { 60 } else { 1 };
|
||||
if let Some(ref mut dec) = decoder {
|
||||
let current = player_state.current_frame + step;
|
||||
dec.seek(((current as f64 / player_state.fps) * 1000.0) as u64)
|
||||
.ok();
|
||||
player_state.current_frame = current;
|
||||
player_state.current_time_ms =
|
||||
let time_ms =
|
||||
((current as f64 / player_state.fps) * 1000.0) as u64;
|
||||
dec.seek(time_ms).ok();
|
||||
player_state.current_frame = current;
|
||||
player_state.current_time_ms = time_ms;
|
||||
sync_audio(
|
||||
&mut audio_player,
|
||||
&config.video,
|
||||
time_ms,
|
||||
player_state.playback == PlaybackState::Playing,
|
||||
);
|
||||
}
|
||||
}
|
||||
sdl2::keyboard::Keycode::Up => {
|
||||
@@ -286,12 +332,13 @@ fn run(config: &Config) -> Result<()> {
|
||||
player_state.playback = PlaybackState::Paused;
|
||||
let ratio = (x - bar_x_start) as f64 / bar_width as f64;
|
||||
let target_frame = (player_state.total_frames as f64 * ratio) as u64;
|
||||
let time_ms =
|
||||
((target_frame as f64 / player_state.fps) * 1000.0) as u64;
|
||||
if let Some(ref mut dec) = decoder {
|
||||
let time_ms =
|
||||
((target_frame as f64 / player_state.fps) * 1000.0) as u64;
|
||||
if dec.seek(time_ms).is_ok() {
|
||||
player_state.current_frame = target_frame;
|
||||
player_state.current_time_ms = time_ms;
|
||||
sync_audio(&mut audio_player, &config.video, time_ms, false);
|
||||
info!(
|
||||
"Seeked to frame {} ({:.1}%)",
|
||||
target_frame,
|
||||
@@ -619,6 +666,22 @@ fn run(config: &Config) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn sync_audio(
|
||||
audio_player: &mut Option<AudioPlayer>,
|
||||
video_path: &Option<std::path::PathBuf>,
|
||||
time_ms: u64,
|
||||
is_playing: bool,
|
||||
) {
|
||||
if let Some(ref mut audio) = audio_player {
|
||||
if let Some(ref path) = video_path {
|
||||
audio.play(path.as_path(), time_ms);
|
||||
if !is_playing {
|
||||
audio.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format_time(ms: u64) -> String {
|
||||
let total_secs = ms / 1000;
|
||||
let hours = total_secs / 3600;
|
||||
|
||||
Reference in New Issue
Block a user