This commit is contained in:
Dominic 2024-05-26 16:15:07 +02:00
parent 14daa1c9f9
commit 4aefb5a647
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
3 changed files with 96 additions and 25 deletions

View file

@ -3,17 +3,18 @@
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
mod iotro;
mod preset;
mod project;
mod question;
mod render;
mod time;
use self::{
iotro::Language,
project::{Project, ProjectLecture, ProjectSource, Resolution},
render::Renderer,
time::{parse_date, parse_time, Time}
};
use crate::preset::Preset;
use camino::Utf8PathBuf as PathBuf;
use clap::Parser;
use console::style;
@ -34,34 +35,24 @@ struct Args {
#[clap(short = 'C', long, default_value = ".")]
directory: PathBuf,
/// The slug of the course, e.g. "23ws-malo2".
#[clap(short = 'c', long, default_value = "23ws-malo2")]
course: String,
/// The label of the course, e.g. "Mathematische Logik II".
#[clap(short, long, default_value = "Mathematische Logik II")]
label: String,
/// The docent of the course, e.g. "Prof. E. Grädel".
#[clap(short, long, default_value = "Prof. E. Grädel")]
docent: String,
/// The language of the lecture. Used for the intro and outro frame.
#[clap(short = 'L', long, default_value = "de")]
lang: Language<'static>,
/// The preset of the lecture. Can be a toml file or a known course slug.
#[clap(short, long)]
preset: String,
#[cfg(feature = "mem_limit")]
/// The memory limit for external tools like ffmpeg.
#[clap(short, long, default_value = "12G")]
mem_limit: String,
/// Transcode the final video clip down to the minimum resolution specified.
/// Transcode the final video clip down to the minimum resolution specified. If not
/// specified, the default value from the preset is used.
#[clap(short, long)]
transcode: Option<Resolution>,
/// Transcode starts at this resolution, or the source resolution, whichever is lower.
#[clap(short = 'T', long, default_value = "1440p")]
transcode_start: Resolution,
/// If not specified, the default value from the preset is used.
#[clap(short = 'T', long)]
transcode_start: Option<Resolution>,
/// Treat the audio as stereo. By default, only one channel from the input stereo will
/// be used, assuming either the other channel is backup or the same as the used.
@ -125,7 +116,8 @@ fn main() {
// process arguments
let directory = args.directory.canonicalize_utf8().unwrap();
let course = args.course;
let preset = Preset::find(&args.preset).unwrap();
let course = preset.course;
// let's see if we need to initialise the project
let project_path = directory.join("project.toml");
@ -170,10 +162,10 @@ fn main() {
let project = Project {
lecture: ProjectLecture {
course,
label: args.label,
docent: args.docent,
label: preset.label,
docent: preset.docent,
date,
lang: args.lang
lang: preset.lang
},
source: ProjectSource {
files,
@ -282,10 +274,10 @@ fn main() {
});
// rescale the video
if let Some(lowest_res) = args.transcode {
if let Some(lowest_res) = args.transcode.or(preset.transcode) {
for res in Resolution::values().into_iter().rev() {
if res > project.source.metadata.as_ref().unwrap().source_res
|| res > args.transcode_start
|| res > args.transcode_start.unwrap_or(preset.transcode_start)
|| res < lowest_res
{
continue;

77
src/preset.rs Normal file
View file

@ -0,0 +1,77 @@
//! This struct defines presets.
use crate::{
iotro::{Language, BRITISH, GERMAN},
project::Resolution
};
use anyhow::bail;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
use std::{fs, io};
#[serde_as]
#[derive(Deserialize, Serialize)]
pub(crate) struct Preset {
// options for the intro slide
pub(crate) course: String,
pub(crate) label: String,
pub(crate) docent: String,
/// Course language
#[serde(default = "Default::default")]
#[serde_as(as = "DisplayFromStr")]
pub(crate) lang: Language<'static>,
// coding options
pub(crate) transcode_start: Resolution,
pub(crate) transcode: Option<Resolution>
}
fn preset_23ws_malo2() -> Preset {
Preset {
course: "23ws-malo2".into(),
label: "Mathematische Logik II".into(),
docent: "Prof. E. Grädel".into(),
lang: GERMAN,
transcode_start: Resolution::WQHD,
transcode: Some(Resolution::nHD)
}
}
fn preset_24ss_algomod() -> Preset {
Preset {
course: "24ss-algomod".into(),
label: "Algorithmische Modelltheorie".into(),
docent: "Prof. E. Grädel".into(),
lang: GERMAN,
transcode_start: Resolution::WQHD,
transcode: Some(Resolution::HD)
}
}
fn preset_24ss_qc() -> Preset {
Preset {
course: "24ss-qc".into(),
label: "Introduction to Quantum Computing".into(),
docent: "Prof. D. Unruh".into(),
lang: BRITISH,
transcode_start: Resolution::WQHD,
transcode: Some(Resolution::HD)
}
}
impl Preset {
pub(crate) fn find(name: &str) -> anyhow::Result<Self> {
match fs::read(name) {
Ok(buf) => return Ok(toml::from_slice(&buf)?),
Err(err) if err.kind() == io::ErrorKind::NotFound => {},
Err(err) => return Err(err.into())
}
Ok(match name {
"23ws-malo2" => preset_23ws_malo2(),
"24ss-algomod" => preset_24ss_algomod(),
"24ss-qc" => preset_24ss_qc(),
_ => bail!("Unknown preset {name:?}")
})
}
}

View file

@ -1,3 +1,5 @@
//! Defines the structure of the `project.toml` file.
use crate::{
iotro::Language,
render::ffmpeg::FfmpegOutputFormat,