Skip to content

Instantly share code, notes, and snippets.

@thomasnield
Created January 29, 2025 18:14
Rust - Calculate Total Length of MP4s in Folder
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