Created
January 29, 2025 18:14
Rust - Calculate Total Length of MP4s in Folder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::process::Command; | |
use walkdir::WalkDir; | |
use regex::Regex; | |
/* | |
[package] | |
name = "rust_playground" | |
version = "0.1.0" | |
edition = "2021" | |
[dependencies] | |
walkdir = "2.5" | |
regex = "1.11" | |
*/ | |
/// Finds all MP4 files recursively in the given directory. | |
fn find_mp4_files(directory: &str) -> Vec<String> { | |
let mut mp4_files = Vec::new(); | |
for entry in WalkDir::new(directory).into_iter().filter_map(Result::ok) { | |
if let Some(ext) = entry.path().extension() { | |
if ext == "mp4" { | |
if let Some(path) = entry.path().to_str() { | |
mp4_files.push(path.to_string()); | |
} | |
} | |
} | |
} | |
mp4_files | |
} | |
/// Uses ffprobe to get the duration of an MP4 file. | |
fn get_mp4_duration(file_path: &str) -> Option<f64> { | |
let output = Command::new("ffprobe") | |
.args([ | |
"-v", "error", | |
"-show_entries", "format=duration", | |
"-of", "json", | |
file_path, | |
]) | |
.output() | |
.ok()?; | |
let output_str = String::from_utf8_lossy(&output.stdout); | |
// Regex to extract the duration from JSON output | |
let re = Regex::new(r#""duration"\s*:\s*"([\d.]+)""#).unwrap(); | |
if let Some(caps) = re.captures(&output_str) { | |
if let Some(duration_str) = caps.get(1) { | |
return duration_str.as_str().parse::<f64>().ok(); | |
} | |
} | |
None | |
} | |
/// Converts total seconds into HH:MM:SS format. | |
fn format_time(seconds: f64) -> String { | |
let hours = (seconds / 3600.0) as u32; | |
let minutes = ((seconds % 3600.0) / 60.0) as u32; | |
let seconds = (seconds % 60.0) as u32; | |
format!("{:02}:{:02}:{:02}", hours, minutes, seconds) | |
} | |
fn main() { | |
let base_directory = "."; // Change this path | |
let mp4_files = find_mp4_files(base_directory); | |
if mp4_files.is_empty() { | |
println!("No MP4 files found."); | |
return; | |
} | |
let mut total_duration = 0.0; | |
for file in &mp4_files { | |
if let Some(duration) = get_mp4_duration(file) { | |
total_duration += duration; | |
} else { | |
println!("Failed to get duration for: {}", file); | |
} | |
} | |
println!( | |
"Total MP4 duration: {} ({:.2} seconds)", | |
format_time(total_duration), | |
total_duration | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment