try to fix it enough to render a lecture

This commit is contained in:
Dominic 2023-10-30 22:48:53 +01:00
parent 228e1648f0
commit 85297910ae
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
3 changed files with 52 additions and 32 deletions

View file

@ -10,13 +10,9 @@ edition = "2021"
anyhow = "1.0"
camino = "1.1"
clap = { version = "4.4", features = ["derive"] }
#ffmpeg = { package = "ffmpeg-next", version = "6.0" }
indexmap = "1.9"
rational = "1.4"
rational = "1.5"
serde = { version = "1.0.188", features = ["derive"] }
serde_with = "3.4"
svgwriter = "0.1"
toml = { package = "basic-toml", version = "0.1.4" }
[patch.crates-io]
rational = { git = "https://github.com/msrd0/rational", branch = "error" }

View file

@ -1,5 +1,5 @@
use crate::time::{format_time, Time};
use std::{borrow::Cow, fmt::Write as _};
use std::{borrow::Cow, collections::VecDeque, fmt::Write as _};
pub(crate) enum Filter {
/// Trim audio and video alike
@ -28,8 +28,7 @@ pub(crate) enum Filter {
/// Concatenate audio and video.
Concat {
inputs: Vec<Cow<'static, str>>,
n: usize,
inputs: VecDeque<Cow<'static, str>>,
output: Cow<'static, str>
},
@ -48,14 +47,14 @@ pub(crate) enum Filter {
output: Cow<'static, str>
},
/// Fast forward. Too complex to explain. Its magic.
/// Fast forward. Will output before, ff, and after parts separately.
FastForward {
input: Cow<'static, str>,
ffinput: Cow<'static, str>,
start: Time,
duration: Time,
multiplier: usize,
output: Cow<'static, str>
output: [Cow<'static, str>; 3]
}
}
@ -152,13 +151,14 @@ impl Filter {
);
},
Self::Concat { inputs, n, output } => {
Self::Concat { inputs, output } => {
for i in inputs {
write!(complex, "{}{}", channel('v', i), channel('a', i));
}
writeln!(
complex,
"concat=n={n}:v=1:a=1{}{};",
"concat=n={}:v=1:a=1{}{};",
inputs.len(),
channel('v', output),
channel('a', output)
);
@ -266,17 +266,23 @@ impl Filter {
channel('v', ffinput)
);
// and finally we concatenate everything back together
writeln!(
complex,
"{}{}{voverlay}{aff}{}{}concat=n=3:v=1:a=1{}{};",
vcut[0],
acut[0],
vcut[2],
acut[2],
channel('v', output),
channel('a', output)
);
// and finally we place everything into the output
for (i, o) in [
(&vcut[0], &output[0]),
(&voverlay, &output[1]),
(&vcut[2], &output[2])
] {
write!(complex, "{i}null{};", channel('v', o));
}
writeln!(complex);
for (i, o) in [
(&acut[0], &output[0]),
(&aff, &output[1]),
(&acut[2], &output[2])
] {
write!(complex, "{i}anull{};", channel('a', o));
}
writeln!(complex);
}
}

View file

@ -15,6 +15,7 @@ use camino::{Utf8Path as Path, Utf8PathBuf as PathBuf};
use rational::Rational;
use std::{
borrow::Cow,
collections::VecDeque,
fs::{self, File},
io::Write as _,
process::{Command, Stdio}
@ -226,7 +227,7 @@ impl<'a> Renderer<'a> {
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/logo.svg"))
)?;
let logo_png = self.target.join("logo.png");
svg2png(&logo_svg, &logo_png, 150 * 1920 / source_res.width())?;
svg2png(&logo_svg, &logo_png, 150 * source_res.width() / 1920)?;
// copy fastforward then render to png
let fastforward_svg = self.target.join("fastforward.svg");
@ -241,7 +242,7 @@ impl<'a> Renderer<'a> {
svg2png(
&fastforward_svg,
&fastforward_png,
128 * 1920 / source_res.width()
128 * source_res.width() / 1920
)?;
Ok(())
@ -251,7 +252,13 @@ impl<'a> Renderer<'a> {
let mut output = self.target.join(format!(
"{}-{}p.mp4",
self.slug,
project.source.metadata.as_ref().unwrap().source_res.width()
project
.source
.metadata
.as_ref()
.unwrap()
.source_res
.height()
));
let mut ffmpeg = Ffmpeg::new(output.clone());
@ -328,26 +335,37 @@ impl<'a> Renderer<'a> {
});
part3 = outrofade.into();
// prepare list for concat
let mut parts = VecDeque::new();
parts.push_back(part2);
// fast-forward the requested parts in reverse order
project.source.fast.sort();
for (i, (ff_st, ff_end)) in project.source.fast.iter().rev().enumerate() {
let recff = format!("recff{i}");
let recff = [
format!("recff{i}b").into(),
format!("recff{i}ff").into(),
format!("recff{i}a").into()
];
ffmpeg.add_filter(Filter::FastForward {
input: part2,
input: parts.pop_front().unwrap(),
ffinput: ff.clone().into(),
start: *ff_st - start,
duration: *ff_end - *ff_st,
multiplier: FF_MULTIPLIER,
output: recff.clone().into()
output: recff.clone()
});
part2 = recff.into();
parts.push_front(recff[2].clone());
parts.push_front(recff[1].clone());
parts.push_front(recff[0].clone());
}
// concatenate everything
parts.push_front(part1);
parts.push_back(part3);
let concat = "concat";
ffmpeg.add_filter(Filter::Concat {
inputs: vec![part1, part2, part3],
n: 3,
inputs: parts,
output: concat.into()
});