diff --git a/src/main.rs b/src/main.rs index cc6e18e..44e034a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ use std::{ fmt::Display, fs, io::{self, BufRead as _, Write}, + str::FromStr, sync::RwLock }; @@ -27,20 +28,27 @@ static MEM_LIMIT: RwLock = RwLock::new(String::new()); #[derive(Debug, Parser)] struct Args { + /// The root directory of the project. It should contain the raw video file(s). #[clap(short = 'C', long, default_value = ".")] directory: PathBuf, - #[clap(short = 'c', long, default_value = "23ws-malo")] + /// The slug of the course, e.g. "23ws-malo2". + #[clap(short = 'c', long, default_value = "23ws-malo2")] course: String, + /// The memory limit for external tools like ffmpeg. #[clap(short, long, default_value = "8G")] - mem_limit: String + mem_limit: String, + + /// Transcode the final video clip down to the minimum resolution specified. + #[clap(short, long)] + transcode: Option } macro_rules! resolutions { ($($res:ident: $width:literal x $height:literal at $bitrate:literal),+) => { #[allow(non_camel_case_types, clippy::upper_case_acronyms)] - #[derive(Clone, Copy, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] + #[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] enum Resolution { $( #[doc = concat!(stringify!($width), "x", stringify!($height))] @@ -77,6 +85,17 @@ macro_rules! resolutions { } } } + + impl FromStr for Resolution { + type Err = anyhow::Error; + + fn from_str(s: &str) -> anyhow::Result { + Ok(match s { + $(concat!(stringify!($height), "p") => Self::$res,)+ + _ => anyhow::bail!("Unknown Resolution: {s:?}") + }) + } + } } } @@ -275,17 +294,21 @@ fn main() { }); // rescale the video - for res in Resolution::values().into_iter().rev() { - if res >= project.source.metadata.as_ref().unwrap().source_res { - continue; - } - if !project.progress.transcoded.contains(&res) { - videos.push(renderer.rescale(res, &project).unwrap()); - project.progress.transcoded.insert(res); + if let Some(lowest_res) = args.transcode { + for res in Resolution::values().into_iter().rev() { + if res >= project.source.metadata.as_ref().unwrap().source_res + || res < lowest_res + { + continue; + } + if !project.progress.transcoded.contains(&res) { + videos.push(renderer.rescale(res, &project).unwrap()); + project.progress.transcoded.insert(res); - println!("{}", toml::to_string(&project).unwrap()); - fs::write(&project_path, toml::to_string(&project).unwrap().as_bytes()) - .unwrap(); + println!("{}", toml::to_string(&project).unwrap()); + fs::write(&project_path, toml::to_string(&project).unwrap().as_bytes()) + .unwrap(); + } } }