feat(player): add frame export (E key) to save PNG

This commit is contained in:
accusys
2026-03-19 02:20:40 +08:00
parent e0f61f0983
commit f6b1802021

View File

@@ -406,6 +406,24 @@ fn run(config: &Config) -> Result<()> {
player_state.speed = 1.0;
info!("Speed: 1.0x");
}
sdl2::keyboard::Keycode::E => {
if let Some(ref info) = video_info {
let frame_num = player_state.current_frame;
let output_dir = std::env::current_dir().unwrap_or_default();
let filename = format!("frame_{:06}.png", frame_num);
let output_path = output_dir.join(&filename);
if let Err(e) = export_current_frame(
&mut texture,
info.width,
info.height,
&output_path,
) {
error!("Failed to export frame: {}", e);
} else {
info!("Exported: {:?}", output_path);
}
}
}
_ => {}
}
}
@@ -927,6 +945,48 @@ fn sync_audio(
}
}
fn export_current_frame(
texture: &mut Option<sdl2::render::Texture>,
width: u32,
height: u32,
output_path: &std::path::Path,
) -> anyhow::Result<()> {
if let Some(ref mut tex) = texture {
let mut pixels = vec![0u8; (width * height * 3) as usize];
tex.with_lock(None, |buffer, _pitch| {
pixels.copy_from_slice(buffer);
});
let surf = sdl2::surface::Surface::from_data(
&mut pixels,
width,
height,
(width * 3) as u32,
sdl2::pixels::PixelFormatEnum::RGB24,
)
.map_err(|e| anyhow::anyhow!("Failed to create surface: {}", e))?;
surf.save_bmp(output_path)
.map_err(|e| anyhow::anyhow!("Failed to save BMP: {}", e))?;
let png_path = output_path.with_extension("png");
let cmd = std::process::Command::new("ffmpeg")
.args(["-y", "-i"])
.arg(output_path.to_str().unwrap_or(""))
.arg(png_path.to_str().unwrap_or(""))
.output()
.map_err(|e| anyhow::anyhow!("Failed to convert to PNG: {}", e))?;
if cmd.status.success() {
std::fs::remove_file(output_path).ok();
}
Ok(())
} else {
anyhow::bail!("No texture available")
}
}
fn format_time(ms: u64) -> String {
let total_secs = ms / 1000;
let hours = total_secs / 3600;