mod command;
mod console_ext;
mod ffprobe;
mod process;
mod sample;
mod svtav1;
mod temporary;
mod vmaf;
mod yuv;
use anyhow::anyhow;
use clap::Parser;
use futures::FutureExt;
use std::{io, time::Duration};
use tokio::signal;
const SAMPLE_SIZE_S: u64 = 20;
const SAMPLE_SIZE: Duration = Duration::from_secs(SAMPLE_SIZE_S);
#[derive(Parser)]
#[clap(version, about)]
enum Command {
SampleEncode(command::sample_encode::Args),
Vmaf(command::vmaf::Args),
Encode(command::encode::Args),
CrfSearch(command::crf_search::Args),
AutoEncode(command::auto_encode::Args),
PrintCompletions(command::print_completions::Args),
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let action = Command::parse();
action.ensure_temp_dir_exists().await?;
let keep = action.keep_temp_files();
let local = tokio::task::LocalSet::new();
let command = local.run_until(match action {
Command::SampleEncode(args) => command::sample_encode(args).boxed_local(),
Command::Vmaf(args) => command::vmaf(args).boxed_local(),
Command::Encode(args) => command::encode(args).boxed_local(),
Command::CrfSearch(args) => command::crf_search(args).boxed_local(),
Command::AutoEncode(args) => command::auto_encode(args).boxed_local(),
Command::PrintCompletions(args) => return command::print_completions(args),
});
let out = tokio::select! {
r = command => r,
_ = signal::ctrl_c() => Err(anyhow!("ctrl_c")),
};
temporary::clean(keep).await;
out
}
impl Command {
fn keep_temp_files(&self) -> bool {
match self {
Self::SampleEncode(args) => args.keep,
_ => false,
}
}
async fn ensure_temp_dir_exists(&self) -> io::Result<()> {
let temp_dir = match self {
Self::SampleEncode(args) => &args.sample.temp_dir,
Self::CrfSearch(args) => &args.sample.temp_dir,
Self::AutoEncode(args) => &args.search.sample.temp_dir,
_ => &None,
};
if let Some(dir) = temp_dir {
tokio::fs::create_dir_all(dir).await?;
}
Ok(())
}
}