diff --git a/src/main.rs b/src/main.rs
index cc6e18e8feed222217f4b085f32187fe321fed30..44e034a3d682070e6037c7269c45dbb3dabce89f 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<String> = 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<Resolution>
 }
 
 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<Self> {
+				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();
+			}
 		}
 	}