From 14daa1c9f953487498a7eec795992104b818cf32 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sun, 26 May 2024 15:23:31 +0200 Subject: [PATCH] add missing file --- src/project.rs | 162 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/project.rs diff --git a/src/project.rs b/src/project.rs new file mode 100644 index 0000000..46ed082 --- /dev/null +++ b/src/project.rs @@ -0,0 +1,162 @@ +use crate::{ + iotro::Language, + render::ffmpeg::FfmpegOutputFormat, + time::{Date, Time} +}; +use rational::Rational; +use serde::{Deserialize, Serialize}; +use serde_with::{serde_as, DisplayFromStr}; +use std::{collections::BTreeSet, str::FromStr}; + +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)] + pub(crate) 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 { + pub(crate) fn values() -> [Self; NUM_RESOLUTIONS] { + [$(Self::$res),+] + } + + pub(crate) fn width(self) -> usize { + match self { + $(Self::$res => $width),+ + } + } + + pub(crate) fn height(self) -> usize { + match self { + $(Self::$res => $height),+ + } + } + + pub(crate) fn bitrate(self) -> u64 { + match self { + $(Self::$res => $bitrate),+ + } + } + + pub(crate) 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 { + 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)] +pub(crate) struct Project { + pub(crate) lecture: ProjectLecture, + pub(crate) source: ProjectSource, + pub(crate) progress: ProjectProgress +} + +#[serde_as] +#[derive(Deserialize, Serialize)] +pub(crate) struct ProjectLecture { + pub(crate) course: String, + pub(crate) label: String, + pub(crate) docent: String, + #[serde_as(as = "DisplayFromStr")] + pub(crate) date: Date, + #[serde(default = "Default::default")] + #[serde_as(as = "DisplayFromStr")] + pub(crate) lang: Language<'static> +} + +#[serde_as] +#[derive(Deserialize, Serialize)] +pub(crate) struct ProjectSource { + pub(crate) files: Vec, + pub(crate) stereo: bool, + + #[serde_as(as = "Option")] + pub(crate) start: Option