From f4adda912a0920703c5d1eac5ad58ab4c494dc6e Mon Sep 17 00:00:00 2001 From: Dominic Date: Tue, 19 Dec 2023 23:56:04 +0100 Subject: [PATCH] use AV1 for 1440p and higher --- src/main.rs | 26 +++++++----- src/render/ffmpeg.rs | 97 ++++++++++++++++++++++++++------------------ src/render/mod.rs | 92 +++++++++++++++++++++++++---------------- 3 files changed, 131 insertions(+), 84 deletions(-) diff --git a/src/main.rs b/src/main.rs index dcf9acd..a6715b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ mod render; mod time; use crate::{ - render::Renderer, + render::{ffmpeg::FfmpegOutputFormat, Renderer}, time::{parse_date, parse_time, Date, Time} }; use camino::Utf8PathBuf as PathBuf; @@ -46,7 +46,7 @@ struct Args { } macro_rules! resolutions { - ($($res:ident: $width:literal x $height:literal at $bitrate:literal),+) => { + ($($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 { @@ -84,6 +84,12 @@ macro_rules! resolutions { $(Self::$res => $bitrate),+ } } + + fn format(self) -> FfmpegOutputFormat { + match self { + $(Self::$res => FfmpegOutputFormat::$format),+ + } + } } impl FromStr for Resolution { @@ -100,12 +106,12 @@ macro_rules! resolutions { } resolutions! { - nHD: 640 x 360 at 500_000, - HD: 1280 x 720 at 1_000_000, - FullHD: 1920 x 1080 at 2_000_000, - WQHD: 2560 x 1440 at 3_000_000, + nHD: 640 x 360 at 500_000 in AvcAac, + HD: 1280 x 720 at 1_000_000 in AvcAac, + FullHD: 1920 x 1080 at 2_000_000 in AvcAac, + WQHD: 2560 x 1440 at 3_000_000 in Av1Opus, // TODO qsx muss mal sagen wieviel bitrate für 4k - UHD: 3840 x 2160 at 4_000_000 + UHD: 3840 x 2160 at 4_000_000 in Av1Opus } #[derive(Deserialize, Serialize)] @@ -234,7 +240,7 @@ fn main() { println!("{}", toml::to_string(&project).unwrap()); let renderer = Renderer::new(&directory, &project).unwrap(); - let recording = renderer.recording_mp4(); + let recording = renderer.recording_mkv(); // preprocess the video if !project.progress.preprocessed { @@ -282,7 +288,7 @@ fn main() { // render the video let mut videos = Vec::new(); videos.push(if project.progress.rendered { - renderer.video_mp4(&project) + renderer.video_file_output() } else { let video = renderer.render(&mut project).unwrap(); project.progress.rendered = true; @@ -302,7 +308,7 @@ fn main() { continue; } if !project.progress.transcoded.contains(&res) { - videos.push(renderer.rescale(res, &project).unwrap()); + videos.push(renderer.rescale(res).unwrap()); project.progress.transcoded.insert(res); println!("{}", toml::to_string(&project).unwrap()); diff --git a/src/render/ffmpeg.rs b/src/render/ffmpeg.rs index 2e2d174..543ad7d 100644 --- a/src/render/ffmpeg.rs +++ b/src/render/ffmpeg.rs @@ -41,7 +41,9 @@ impl FfmpegInput { cmd.arg("-r").arg(fps.to_string()); } if let Some(start) = self.start { - cmd.arg("-seek_streams_individually").arg("false"); + if self.path.ends_with(".mp4") { + cmd.arg("-seek_streams_individualy").arg("false"); + } cmd.arg("-ss").arg(format_time(start)); } if let Some(duration) = self.duration { @@ -51,18 +53,35 @@ impl FfmpegInput { } } +pub(crate) enum FfmpegOutputFormat { + /// AV1 / FLAC + Av1Flac, + /// AV1 / OPUS + Av1Opus, + /// AVC (H.264) / AAC + AvcAac +} + pub(crate) struct FfmpegOutput { + pub(crate) format: FfmpegOutputFormat, + pub(crate) audio_bitrate: Option, + pub(crate) video_bitrate: Option, + pub(crate) fps: Option, pub(crate) duration: Option