allow preprocessing to keep stereo; asks which files to use

This commit is contained in:
Dominic 2024-01-06 18:55:27 +01:00
parent f4adda912a
commit 5c50b33251
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
3 changed files with 47 additions and 11 deletions

View file

@ -37,12 +37,17 @@ struct Args {
course: String, course: String,
/// The memory limit for external tools like ffmpeg. /// The memory limit for external tools like ffmpeg.
#[clap(short, long, default_value = "8G")] #[clap(short, long, default_value = "12G")]
mem_limit: String, mem_limit: String,
/// Transcode the final video clip down to the minimum resolution specified. /// Transcode the final video clip down to the minimum resolution specified.
#[clap(short, long)] #[clap(short, long)]
transcode: Option<Resolution> transcode: Option<Resolution>,
/// Treat the audio as stereo. By default, only one channel from the input stereo will
/// be used, assuming either the other channel is backup or the same as the used.
#[clap(short, long, default_value = "false")]
stereo: bool
} }
macro_rules! resolutions { macro_rules! resolutions {
@ -133,6 +138,7 @@ struct ProjectLecture {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
struct ProjectSource { struct ProjectSource {
files: Vec<String>, files: Vec<String>,
stereo: bool,
#[serde_as(as = "Option<DisplayFromStr>")] #[serde_as(as = "Option<DisplayFromStr>")]
start: Option<Time>, start: Option<Time>,
@ -171,6 +177,18 @@ struct ProjectProgress {
transcoded: BTreeSet<Resolution> transcoded: BTreeSet<Resolution>
} }
fn ask(question: impl Display) -> String {
let mut stdout = io::stdout().lock();
let mut stdin = io::stdin().lock();
writeln!(stdout, "{question}").unwrap();
let mut line = String::new();
write!(stdout, "> ").unwrap();
stdout.flush().unwrap();
stdin.read_line(&mut line).unwrap();
line.trim().to_owned()
}
fn ask_time(question: impl Display) -> Time { fn ask_time(question: impl Display) -> Time {
let mut stdout = io::stdout().lock(); let mut stdout = io::stdout().lock();
let mut stdin = io::stdin().lock(); let mut stdin = io::stdin().lock();
@ -212,7 +230,9 @@ fn main() {
let entry = entry.unwrap(); let entry = entry.unwrap();
let name = entry.file_name(); let name = entry.file_name();
let lower = name.to_ascii_lowercase(); let lower = name.to_ascii_lowercase();
if (lower.ends_with(".mp4") || lower.ends_with(".mts")) if (lower.ends_with(".mp4")
|| lower.ends_with(".mts")
|| lower.ends_with(".mkv"))
&& entry.file_type().unwrap().is_file() && entry.file_type().unwrap().is_file()
{ {
files.push(String::from(name)); files.push(String::from(name));
@ -220,12 +240,19 @@ fn main() {
} }
files.sort_unstable(); files.sort_unstable();
assert!(!files.is_empty()); assert!(!files.is_empty());
println!("I found the following source files: {files:?}"); println!("I found the following source files: {files:?}");
files = ask("Which source files would you like to use? (specify multiple files separated by whitespace)")
.split_ascii_whitespace()
.map(String::from)
.collect();
assert!(!files.is_empty());
let project = Project { let project = Project {
lecture: ProjectLecture { course, date }, lecture: ProjectLecture { course, date },
source: ProjectSource { source: ProjectSource {
files, files,
stereo: args.stereo,
start: None, start: None,
end: None, end: None,
fast: Vec::new(), fast: Vec::new(),

View file

@ -157,7 +157,9 @@ enum FfmpegFilter {
filters: Vec<Filter>, filters: Vec<Filter>,
output: Cow<'static, str> output: Cow<'static, str>
}, },
Loudnorm, Loudnorm {
stereo: bool
},
Rescale(Resolution) Rescale(Resolution)
} }
@ -216,10 +218,14 @@ impl Ffmpeg {
self self
} }
pub fn enable_loudnorm(&mut self) -> &mut Self { pub fn enable_loudnorm(&mut self, loudnorm_stereo: bool) -> &mut Self {
match &mut self.filter { match &mut self.filter {
FfmpegFilter::None => self.filter = FfmpegFilter::Loudnorm, FfmpegFilter::None => {
FfmpegFilter::Loudnorm => {}, self.filter = FfmpegFilter::Loudnorm {
stereo: loudnorm_stereo
}
},
FfmpegFilter::Loudnorm { stereo } if *stereo == loudnorm_stereo => {},
_ => panic!("An incompatible type of filter has been set before") _ => panic!("An incompatible type of filter has been set before")
} }
self self
@ -228,7 +234,6 @@ impl Ffmpeg {
pub fn rescale_video(&mut self, res: Resolution) -> &mut Self { pub fn rescale_video(&mut self, res: Resolution) -> &mut Self {
match &mut self.filter { match &mut self.filter {
FfmpegFilter::None => self.filter = FfmpegFilter::Rescale(res), FfmpegFilter::None => self.filter = FfmpegFilter::Rescale(res),
FfmpegFilter::Loudnorm => {},
_ => panic!("An incompatible type of filter has been set before") _ => panic!("An incompatible type of filter has been set before")
} }
self self
@ -243,7 +248,7 @@ impl Ffmpeg {
let (vdec, venc, aenc) = match &self.filter { let (vdec, venc, aenc) = match &self.filter {
FfmpegFilter::None => (false, false, false), FfmpegFilter::None => (false, false, false),
FfmpegFilter::Filters { .. } => (false, true, true), FfmpegFilter::Filters { .. } => (false, true, true),
FfmpegFilter::Loudnorm => (false, false, true), FfmpegFilter::Loudnorm { .. } => (false, false, true),
FfmpegFilter::Rescale(_) => (true, true, false) FfmpegFilter::Rescale(_) => (true, true, false)
}; };
@ -286,7 +291,7 @@ impl Ffmpeg {
cmd.arg("-map").arg("[v]"); cmd.arg("-map").arg("[v]");
cmd.arg("-map").arg(channel('a', &output)); cmd.arg("-map").arg(channel('a', &output));
}, },
FfmpegFilter::Loudnorm => { FfmpegFilter::Loudnorm { stereo: false } => {
cmd.arg("-af").arg(concat!( cmd.arg("-af").arg(concat!(
"pan=mono|c0=FR,", "pan=mono|c0=FR,",
"loudnorm=dual_mono=true:print_format=summary,", "loudnorm=dual_mono=true:print_format=summary,",
@ -294,6 +299,10 @@ impl Ffmpeg {
"aformat=sample_rates=48000" "aformat=sample_rates=48000"
)); ));
}, },
FfmpegFilter::Loudnorm { stereo: true } => {
cmd.arg("-af")
.arg("loudnorm=print_format=summary,aformat=sample_rates=48000");
},
FfmpegFilter::Rescale(res) => { FfmpegFilter::Rescale(res) => {
cmd.arg("-vf").arg(if vaapi { cmd.arg("-vf").arg(if vaapi {
format!("scale_vaapi=w={}:h={}", res.width(), res.height()) format!("scale_vaapi=w={}:h={}", res.width(), res.height())

View file

@ -211,7 +211,7 @@ impl<'a> Renderer<'a> {
concat: true, concat: true,
..FfmpegInput::new(recording_txt) ..FfmpegInput::new(recording_txt)
}); });
ffmpeg.enable_loudnorm(); ffmpeg.enable_loudnorm(project.source.stereo);
ffmpeg.run()?; ffmpeg.run()?;
let width = ffprobe_video("stream=width", &recording_mkv)?.parse()?; let width = ffprobe_video("stream=width", &recording_mkv)?.parse()?;