add missing file

This commit is contained in:
Dominic 2024-05-26 15:23:31 +02:00
parent 78609dec9a
commit 14daa1c9f9
Signed by: msrd0
GPG key ID: DCC8C247452E98F9

162
src/project.rs Normal file
View file

@ -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<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)]
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<String>,
pub(crate) stereo: bool,
#[serde_as(as = "Option<DisplayFromStr>")]
pub(crate) start: Option<Time>,
#[serde_as(as = "Option<DisplayFromStr>")]
pub(crate) end: Option<Time>,
#[serde(default)]
#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr)>")]
pub(crate) fast: Vec<(Time, Time)>,
#[serde(default)]
#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr, _)>")]
pub(crate) questions: Vec<(Time, Time, String)>,
pub(crate) metadata: Option<ProjectSourceMetadata>
}
#[serde_as]
#[derive(Deserialize, Serialize)]
pub(crate) struct ProjectSourceMetadata {
/// The duration of the source video.
#[serde_as(as = "DisplayFromStr")]
pub(crate) source_duration: Time,
/// The FPS of the source video.
#[serde_as(as = "DisplayFromStr")]
pub(crate) source_fps: Rational,
/// The time base of the source video.
#[serde_as(as = "DisplayFromStr")]
pub(crate) source_tbn: Rational,
/// The resolution of the source video.
pub(crate) source_res: Resolution,
/// The sample rate of the source audio.
pub(crate) source_sample_rate: u32
}
#[derive(Default, Deserialize, Serialize)]
pub(crate) struct ProjectProgress {
#[serde(default)]
pub(crate) preprocessed: bool,
#[serde(default)]
pub(crate) asked_start_end: bool,
#[serde(default)]
pub(crate) asked_fast: bool,
#[serde(default)]
pub(crate) asked_questions: bool,
#[serde(default)]
pub(crate) rendered_assets: bool,
#[serde(default)]
pub(crate) rendered: bool,
#[serde(default)]
pub(crate) transcoded: BTreeSet<Resolution>
}