mod app; mod ffmpeg; mod ops; mod recipes; mod ui; use std::process::Command; use std::time::Duration; use anyhow::{bail, Result}; use ratatui::crossterm::event::{self, Event, KeyEventKind}; use ratatui::DefaultTerminal; use app::App; fn main() -> Result<()> { let mut initial: Vec = Vec::new(); for arg in std::env::args().skip(1) { match arg.as_str() { "--version" | "-V" => { println!("lazyff {}", env!("CARGO_PKG_VERSION")); return Ok(()); } "--help" | "-h" => { println!("lazyff {} — a friendly TUI for FFmpeg", env!("CARGO_PKG_VERSION")); println!("Usage: lazyff [FILE...]"); println!(" no argument open a file browser in the current directory"); println!(" FILE open this video/audio file straight in the editor"); println!(" FILE FILE... open several files together in batch mode"); return Ok(()); } _ => { let path = std::path::PathBuf::from(&arg); if !path.is_file() { bail!("{arg}: no such file"); } initial.push(path); } } } for bin in ["ffmpeg", "ffprobe"] { if Command::new(bin).arg("-version").output().is_err() { bail!("{bin} was not found on your PATH. Please install FFmpeg first."); } } // Probe the initial file before entering the alternate screen so errors // print normally. let app = App::new(initial)?; let mut terminal = ratatui::init(); let result = run(&mut terminal, app); ratatui::restore(); result } fn run(terminal: &mut DefaultTerminal, mut app: App) -> Result<()> { loop { app.poll_run_messages(); terminal.draw(|f| ui::draw(f, &mut app))?; if event::poll(Duration::from_millis(100))? { if let Event::Key(key) = event::read()? { if key.kind == KeyEventKind::Press { app.on_key(key); } } } if app.should_quit { return Ok(()); } } }