Update main.rs with complete implementation
This commit is contained in:
158
src/main.rs
158
src/main.rs
@@ -1,38 +1,32 @@
|
||||
//! MoMentry Playground 主入口
|
||||
//! MoMentry Playground - Main entry point
|
||||
//!
|
||||
//! Unified media player with ASR/YOLO/Chunks overlay support
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use log::{error, info};
|
||||
use std::path::Path;
|
||||
|
||||
mod config;
|
||||
mod overlay;
|
||||
mod player;
|
||||
mod ui;
|
||||
mod viewer;
|
||||
mod api;
|
||||
mod input;
|
||||
mod web;
|
||||
|
||||
use player::VideoPlayer;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "momentry")]
|
||||
#[command(about = "MoMentry Playground - 統一播放、檢視、監控")]
|
||||
struct Args {
|
||||
#[arg(short, long, default_value = "800")]
|
||||
width: u32,
|
||||
|
||||
#[arg(short, long, default_value = "600")]
|
||||
height: u32,
|
||||
|
||||
#[arg(short, long)]
|
||||
file: Option<String>,
|
||||
}
|
||||
use config::Config;
|
||||
use overlay::{AsrLoader, YoloLoader};
|
||||
use player::{Video, Renderer, PlaybackState};
|
||||
use player::state::PlayerState;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
||||
env_logger::Builder::from_env(
|
||||
env_logger::Env::default().default_filter_or("info")
|
||||
).init();
|
||||
|
||||
let args = Args::parse();
|
||||
let config = Config::load();
|
||||
info!("MoMentry Playground starting...");
|
||||
info!("Window: {}x{}", config.width, config.height);
|
||||
|
||||
if let Err(e) = run(args) {
|
||||
if let Err(e) = run(&config) {
|
||||
error!("Application error: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
@@ -40,21 +34,123 @@ fn main() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(args: Args) -> Result<()> {
|
||||
info!("Initializing window: {}x{}", args.width, args.height);
|
||||
info!("Initializing video player...");
|
||||
fn run(config: &Config) -> Result<()> {
|
||||
let mut video = Video::new();
|
||||
let mut renderer = Renderer::new("MoMentry Playground", config.width, config.height)?;
|
||||
|
||||
let mut player = VideoPlayer::new()?;
|
||||
let mut asr: Option<AsrLoader> = None;
|
||||
let mut yolo: Option<YoloLoader> = None;
|
||||
|
||||
if let Some(path) = args.file {
|
||||
info!("Loading file: {}", path);
|
||||
player.open(&path)?;
|
||||
player.play()?;
|
||||
if let Some(ref video_path) = config.video {
|
||||
info!("Loading video: {:?}", video_path);
|
||||
let info_data = video.open(video_path)?;
|
||||
info!("Video info: {}x{} @ {:.2}fps, {} frames",
|
||||
info_data.width, info_data.height, info_data.fps, info_data.total_frames);
|
||||
|
||||
renderer.create_texture(info_data.width, info_data.height)?;
|
||||
}
|
||||
|
||||
if let Some(ref asr_path) = config.asr {
|
||||
info!("Loading ASR: {:?}", asr_path);
|
||||
match AsrLoader::load(asr_path) {
|
||||
Ok(loader) => {
|
||||
info!("ASR loaded: {} segments", loader.segment_count());
|
||||
asr = Some(loader);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to load ASR: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref yolo_path) = config.yolo {
|
||||
info!("Loading YOLO: {:?}", yolo_path);
|
||||
match YoloLoader::load(yolo_path) {
|
||||
Ok(loader) => {
|
||||
info!("YOLO loaded: {} frames", loader.total_frames());
|
||||
yolo = Some(loader);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to load YOLO: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config.fullscreen {
|
||||
renderer.set_fullscreen(true)?;
|
||||
}
|
||||
|
||||
let mut player_state = PlayerState::default();
|
||||
if let Some(info) = video.get_info() {
|
||||
player_state.total_frames = info.total_frames;
|
||||
player_state.duration_ms = info.duration_ms;
|
||||
player_state.fps = info.fps;
|
||||
}
|
||||
|
||||
info!("Main loop started - waiting for events...");
|
||||
|
||||
if let Some(ref video_path) = config.video {
|
||||
video.play()?;
|
||||
player_state.playback = PlaybackState::Playing;
|
||||
run_playback_loop(&mut video, &mut renderer, &mut player_state, &mut asr, &mut yolo)?;
|
||||
}
|
||||
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
fn run_playback_loop(
|
||||
video: &mut Video,
|
||||
renderer: &mut Renderer,
|
||||
state: &mut PlayerState,
|
||||
asr: &mut Option<AsrLoader>,
|
||||
yolo: &mut Option<YoloLoader>,
|
||||
) -> Result<()> {
|
||||
let frame_duration = std::time::Duration::from_millis(16);
|
||||
|
||||
loop {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
match video.read_frame() {
|
||||
Ok(Some(frame)) => {
|
||||
state.current_frame = frame.frame_number;
|
||||
state.current_time_ms = frame.timestamp_ms;
|
||||
|
||||
renderer.update_texture(&frame.data)?;
|
||||
|
||||
if state.show_yolo {
|
||||
if let Some(ref mut yolo_loader) = yolo {
|
||||
let detections = yolo_loader.get_detections(frame.frame_number);
|
||||
for det in detections {
|
||||
renderer.draw_bbox(
|
||||
det.x1 as i32,
|
||||
det.y1 as i32,
|
||||
(det.x2 - det.x1) as u32,
|
||||
(det.y2 - det.y1) as u32,
|
||||
&det.class_name,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderer.present();
|
||||
}
|
||||
Ok(None) => {
|
||||
info!("Playback ended");
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Frame read error: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let elapsed = start.elapsed();
|
||||
if elapsed < frame_duration {
|
||||
std::thread::sleep(frame_duration - elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user