move project structs into their own mod

This commit is contained in:
Dominic 2024-05-26 15:20:40 +02:00
parent b6bd1be12e
commit 1dfe835587
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
2 changed files with 7 additions and 164 deletions

View file

@ -3,30 +3,26 @@
#![forbid(elided_lifetimes_in_paths, unsafe_code)] #![forbid(elided_lifetimes_in_paths, unsafe_code)]
mod iotro; mod iotro;
mod project;
mod question; mod question;
mod render; mod render;
mod time; mod time;
use self::{ use self::{
iotro::Language, iotro::Language,
question::Question, project::{Project, ProjectLecture, ProjectSource, Resolution},
render::{ffmpeg::FfmpegOutputFormat, Renderer}, render::Renderer,
time::{parse_date, parse_time, Date, Time} time::{parse_date, parse_time, Time}
}; };
use camino::Utf8PathBuf as PathBuf; use camino::Utf8PathBuf as PathBuf;
use clap::Parser; use clap::Parser;
use console::style; use console::style;
use rational::Rational;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
#[cfg(feature = "mem_limit")] #[cfg(feature = "mem_limit")]
use std::sync::RwLock; use std::sync::RwLock;
use std::{ use std::{
collections::BTreeSet,
fmt::Display, fmt::Display,
fs, fs,
io::{self, BufRead as _, Write}, io::{self, BufRead as _, Write}
str::FromStr
}; };
#[cfg(feature = "mem_limit")] #[cfg(feature = "mem_limit")]
@ -73,159 +69,6 @@ struct Args {
stereo: bool stereo: bool
} }
macro_rules! resolutions {
($($res:ident: $width:literal x $height:literal at $bitrate:literal in $format:ident),+) => {
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
enum Resolution {
$(
#[doc = concat!(stringify!($width), "x", stringify!($height))]
$res
),+
}
const NUM_RESOLUTIONS: usize = {
let mut num = 0;
$(num += 1; stringify!($res);)+
num
};
impl Resolution {
fn values() -> [Self; NUM_RESOLUTIONS] {
[$(Self::$res),+]
}
fn width(self) -> usize {
match self {
$(Self::$res => $width),+
}
}
fn height(self) -> usize {
match self {
$(Self::$res => $height),+
}
}
fn bitrate(self) -> u64 {
match self {
$(Self::$res => $bitrate),+
}
}
fn format(self) -> FfmpegOutputFormat {
match self {
$(Self::$res => FfmpegOutputFormat::$format),+
}
}
}
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:?}")
})
}
}
}
}
resolutions! {
nHD: 640 x 360 at 500_000 in AvcAac,
HD: 1280 x 720 at 1_000_000 in AvcAac,
FullHD: 1920 x 1080 at 750_000 in Av1Opus,
WQHD: 2560 x 1440 at 1_000_000 in Av1Opus,
// TODO qsx muss mal sagen wieviel bitrate für 4k
UHD: 3840 x 2160 at 2_000_000 in Av1Opus
}
#[derive(Deserialize, Serialize)]
struct Project {
lecture: ProjectLecture,
source: ProjectSource,
progress: ProjectProgress
}
#[serde_as]
#[derive(Deserialize, Serialize)]
struct ProjectLecture {
course: String,
label: String,
docent: String,
#[serde_as(as = "DisplayFromStr")]
date: Date,
#[serde(default = "Default::default")]
#[serde_as(as = "DisplayFromStr")]
lang: Language<'static>
}
#[serde_as]
#[derive(Deserialize, Serialize)]
struct ProjectSource {
files: Vec<String>,
stereo: bool,
#[serde_as(as = "Option<DisplayFromStr>")]
start: Option<Time>,
#[serde_as(as = "Option<DisplayFromStr>")]
end: Option<Time>,
#[serde(default)]
#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr)>")]
fast: Vec<(Time, Time)>,
#[serde(default)]
#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr, _)>")]
questions: Vec<(Time, Time, String)>,
metadata: Option<ProjectSourceMetadata>
}
#[serde_as]
#[derive(Deserialize, Serialize)]
struct ProjectSourceMetadata {
/// The duration of the source video.
#[serde_as(as = "DisplayFromStr")]
source_duration: Time,
/// The FPS of the source video.
#[serde_as(as = "DisplayFromStr")]
source_fps: Rational,
/// The time base of the source video.
#[serde_as(as = "DisplayFromStr")]
source_tbn: Rational,
/// The resolution of the source video.
source_res: Resolution,
/// The sample rate of the source audio.
source_sample_rate: u32
}
#[derive(Default, Deserialize, Serialize)]
struct ProjectProgress {
#[serde(default)]
preprocessed: bool,
#[serde(default)]
asked_start_end: bool,
#[serde(default)]
asked_fast: bool,
#[serde(default)]
asked_questions: bool,
#[serde(default)]
rendered_assets: bool,
#[serde(default)]
rendered: bool,
#[serde(default)]
transcoded: BTreeSet<Resolution>
}
fn ask(question: impl Display) -> String { fn ask(question: impl Display) -> String {
let mut stdout = io::stdout().lock(); let mut stdout = io::stdout().lock();
let mut stdin = io::stdin().lock(); let mut stdin = io::stdin().lock();

View file

@ -7,10 +7,10 @@ use self::{
}; };
use crate::{ use crate::{
iotro::{intro, outro}, iotro::{intro, outro},
project::{Project, ProjectLecture, ProjectSourceMetadata, Resolution},
question::Question, question::Question,
render::ffmpeg::{Ffmpeg, FfmpegInput}, render::ffmpeg::{Ffmpeg, FfmpegInput},
time::{format_date, format_time, Time}, time::{format_date, format_time, Time}
Project, ProjectLecture, ProjectSourceMetadata, Resolution
}; };
use anyhow::{bail, Context}; use anyhow::{bail, Context};
use camino::{Utf8Path as Path, Utf8PathBuf as PathBuf}; use camino::{Utf8Path as Path, Utf8PathBuf as PathBuf};