add missing file
This commit is contained in:
parent
78609dec9a
commit
14daa1c9f9
1 changed files with 162 additions and 0 deletions
162
src/project.rs
Normal file
162
src/project.rs
Normal 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>
|
||||||
|
}
|
Loading…
Reference in a new issue