feat: argparse and dry-run.
This commit is contained in:
123
src/merge.rs
123
src/merge.rs
@@ -1,86 +1,57 @@
|
||||
use crate::audio_converter::convert_audio_to_aac;
|
||||
use crate::dry_run::{print_shell_script_header, ShellScript};
|
||||
use crate::file_finder::{find_audio_file, find_largest_video_file};
|
||||
use crate::video_merger::merge_video_and_audio;
|
||||
use std::io::Result;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::{fs, io};
|
||||
use std::path::Path;
|
||||
|
||||
fn guess_video_path(path: &Path) -> Result<PathBuf> {
|
||||
let mut largest_size = 0;
|
||||
let mut largest_file = PathBuf::from(path);
|
||||
for entry in fs::read_dir(path)? {
|
||||
let entry_path = entry?.path().canonicalize()?;
|
||||
if entry_path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let size = entry_path.metadata()?.len();
|
||||
if size >= largest_size {
|
||||
largest_size = size;
|
||||
largest_file = entry_path.into();
|
||||
}
|
||||
pub fn merge_video_from_path(path: &Path, dry_run: bool, overwrite: bool) -> Result<()> {
|
||||
if dry_run {
|
||||
println!("=== DRY RUN MODE ===");
|
||||
println!("This is a dry run. Below is the shell script that would be executed:");
|
||||
println!();
|
||||
print_shell_script_header();
|
||||
}
|
||||
|
||||
Ok(largest_file)
|
||||
}
|
||||
println!("Step 1: Searching for video file in: {}", path.display());
|
||||
let video_path = find_largest_video_file(path)?;
|
||||
println!("Found video file: {}", video_path.display());
|
||||
|
||||
fn convert_audio_to_aac(path: &Path) -> Result<()> {
|
||||
let save_path = path.with_extension("aac");
|
||||
let output = Command::new("ffmpeg")
|
||||
.arg("-y")
|
||||
.arg("-hide_banner")
|
||||
.arg("-i").arg(path)
|
||||
.arg("-c").arg("copy")
|
||||
.arg(save_path)
|
||||
.spawn()?.wait_with_output();
|
||||
if dry_run {
|
||||
let mut script = ShellScript::new();
|
||||
script.add_comment("File paths");
|
||||
script.add_variable("VIDEO_FILE", &video_path);
|
||||
crate::dry_run::print_shell_script(&script);
|
||||
}
|
||||
|
||||
match output {
|
||||
Ok(res) => {
|
||||
if !res.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("ffmpeg exited with status {}", res.status)));
|
||||
}
|
||||
}
|
||||
Err(e) => return Err(e)
|
||||
println!("Step 2: Looking for corresponding audio file...");
|
||||
let audio_path = find_audio_file(&video_path)?;
|
||||
println!("Found audio file: {}", audio_path.display());
|
||||
|
||||
if dry_run {
|
||||
let mut script = ShellScript::new();
|
||||
script.add_variable("AUDIO_FILE", &audio_path);
|
||||
crate::dry_run::print_shell_script(&script);
|
||||
}
|
||||
|
||||
println!();
|
||||
println!("Step 3: Converting audio to AAC format...");
|
||||
let aac_path = convert_audio_to_aac(&audio_path, dry_run, overwrite)?;
|
||||
println!();
|
||||
|
||||
println!("Step 4: Merging video and audio...");
|
||||
let output_path = merge_video_and_audio(&video_path, &aac_path, dry_run, overwrite)?;
|
||||
|
||||
if dry_run {
|
||||
println!();
|
||||
println!("=== DRY RUN COMPLETE ===");
|
||||
println!("To actually perform these operations, run without -n flag.");
|
||||
println!("You can also copy the shell script above and execute it manually.");
|
||||
} else {
|
||||
println!();
|
||||
println!("=== MERGE COMPLETE ===");
|
||||
println!("Video file: {}", output_path.display());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn merge(video_path: &Path, audio_path: &Path) -> Result<()> {
|
||||
let origin_video_extension = video_path.extension().unwrap().to_str().unwrap();
|
||||
let origin_filename = format!("original.{}", &origin_video_extension);
|
||||
let origin_path = video_path.parent().unwrap().join(origin_filename);
|
||||
fs::rename(video_path, &origin_path)?;
|
||||
let output = Command::new("ffmpeg")
|
||||
.arg("-y")
|
||||
.arg("-hide_banner")
|
||||
.arg("-i").arg(origin_path)
|
||||
.arg("-i").arg(audio_path)
|
||||
.arg("-c").arg("copy")
|
||||
.arg(video_path)
|
||||
.spawn()?.wait_with_output();
|
||||
|
||||
match output {
|
||||
Ok(res) => {
|
||||
if !res.status.success() {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, format!("ffmpeg exited with status {}", res.status)));
|
||||
}
|
||||
}
|
||||
Err(e) => return Err(e)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn merge_video_from_path(path: &Path) -> Result<()> {
|
||||
let video_path = guess_video_path(path)?;
|
||||
let video_name = video_path.file_name().unwrap().to_str().unwrap();
|
||||
let video_extension = video_path.extension().unwrap();
|
||||
|
||||
let audio_name = format!("{}.m4a", &video_name[..video_name.len() - video_extension.len() - 1]);
|
||||
let audio_path = video_path.parent().unwrap().join(audio_name);
|
||||
if !audio_path.exists() {
|
||||
return Err(io::Error::new(io::ErrorKind::NotFound, "Audio file does not exist"));
|
||||
}
|
||||
|
||||
convert_audio_to_aac(&audio_path).expect("Audio file corrupted.");
|
||||
merge(&video_path, &audio_path)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user