### Create Video Hashes with Custom Options (Rust) Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Illustrates how to customize video hash generation using `VideoHashBuilder` by providing specific `CreationOptions`. This allows control over parameters like `skip_forward_amount`, `duration`, and `cropdetect` (e.g., `Letterbox` or `Motion`). Requires the `vid_dup_finder_lib` crate and FFmpeg installation. ```rust use vid_dup_finder_lib::{VideoHashBuilder, CreationOptions, Cropdetect}; use std::path::PathBuf; fn main() -> Result<(), Box> { // Custom options: skip 60s intro, process 20s of content, detect letterboxing let options = CreationOptions { skip_forward_amount: 60.0, // Skip first 60 seconds duration: 20.0, // Hash from 20 seconds of content cropdetect: Cropdetect::Letterbox, // Auto-detect black bars }; let builder = VideoHashBuilder::from_options(options); // Process TV show episodes with long intros let episode = PathBuf::from("/tv_shows/series_s01e01.mp4"); let hash = builder.hash(episode)?; println!("Created hash for: {}", hash.src_path().display()); println!("Video duration: {} seconds", hash.duration()); // Use Motion cropdetect for videos with moving letterboxes let motion_options = CreationOptions { skip_forward_amount: 0.0, duration: 15.0, cropdetect: Cropdetect::Motion, }; let motion_builder = VideoHashBuilder::from_options(motion_options); let short_video = PathBuf::from("/videos/short_clip.mp4"); match motion_builder.hash(short_video) { Ok(h) => println!("Hash created successfully"), Err(e) => eprintln!("Error: {}", e), } Ok(()) } ``` -------------------------------- ### Find Unique Videos in a Directory using CLI Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Illustrates how to use the `vid_dup_finder` command-line tool with the `--search-unique` flag to find videos that are not duplicates within a given directory. The command syntax and an example of the output, listing only the unique video files, are provided. ```bash # Find unique videos (no duplicates) vid_dup_finder --files /path/to/videos --search-unique # Example output: # Unique videos: # /path/to/videos/bird_video.mp4 # /path/to/videos/fish_video.mp4 ``` -------------------------------- ### Find Duplicate Videos in a Directory using CLI Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Demonstrates how to use the `vid_dup_finder` command-line tool to find all duplicate videos within a specified directory and its subdirectories. It shows the command syntax and an example of the expected output format, which lists duplicate groups and the files within each group. ```bash # Find all duplicates in a directory vid_dup_finder --files /path/to/videos # Example output: # Found 2 duplicate groups # # Group: 0, entries: 3 # /path/to/videos/cat_original.mp4 # /path/to/videos/cat_copy.mp4 # /path/to/videos/cat_resized.webm # # Group: 1, entries: 2 # /path/to/videos/dog_video.mp4 # /path/to/videos/dog_reencoded.mp4 ``` -------------------------------- ### Configure Search Tolerance for Duplicate Video Detection Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Illustrates how to configure search tolerance for finding duplicate videos using `VideoHashBuilder` and the `search` function. It demonstrates the impact of different tolerance levels (default, strict, lenient, very lenient) on the number of detected duplicate groups. The recommendation is to start with the default and adjust based on false positive rates. ```rust use vid_dup_finder_lib::{VideoHashBuilder, search, DEFAULT_SEARCH_TOLERANCE}; use std::path::PathBuf; fn main() -> Result<(), Box> { let builder = VideoHashBuilder::default(); let videos = vec![ "/videos/original.mp4", "/videos/slightly_different.mp4", "/videos/very_different.mp4", ]; let hashes: Vec<_> = videos .into_iter() .filter_map(|p| builder.hash(PathBuf::from(p)).ok()) .collect(); // Default tolerance: 0.35 (good starting point) println!("Default tolerance (0.35):"); let groups_default = search(hashes.clone(), DEFAULT_SEARCH_TOLERANCE); println!(" Found {} groups", groups_default.len()); // Strict tolerance: 0.15 (fewer false positives, may miss some duplicates) println!("\nStrict tolerance (0.15):"); let groups_strict = search(hashes.clone(), 0.15); println!(" Found {} groups", groups_strict.len()); // Lenient tolerance: 0.50 (more duplicates found, more false positives) println!("\nLenient tolerance (0.50):"); let groups_lenient = search(hashes.clone(), 0.50); println!(" Found {} groups", groups_lenient.len()); // Very lenient: 0.75 (will match very different videos) println!("\nVery lenient tolerance (0.75):"); let groups_very_lenient = search(hashes.clone(), 0.75); println!(" Found {} groups", groups_very_lenient.len()); // Tolerance recommendations: // 0.15-0.25: Only very similar videos (minimal compression differences) // 0.30-0.40: Good for finding duplicates with minor differences (DEFAULT) // 0.45-0.60: Lenient matching, may include similar but not duplicate videos // 0.60+: Will produce many false positives // Start with DEFAULT_SEARCH_TOLERANCE and adjust based on results: // - Too many false positives? Lower the tolerance // - Missing obvious duplicates? Raise the tolerance Ok(()) } ``` -------------------------------- ### Process Duplicate Video Groups with Rust Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt This Rust code demonstrates how to use the `search` function to find groups of duplicate videos and then process these groups. It shows how to iterate through groups, check for reference videos, list duplicates, and optionally delete duplicate files while keeping one. It also shows how to get pairwise combinations of duplicates within a group. ```rust use vid_dup_finder_lib::{VideoHashBuilder, search, search_with_references, DEFAULT_SEARCH_TOLERANCE}; use std::path::{Path, PathBuf}; fn main() -> Result<(), Box> { let builder = VideoHashBuilder::default(); // Create sample hashes let videos = vec![ "/videos/cat1.mp4", "/videos/cat1_copy.mp4", "/videos/cat1_resized.webm", "/videos/dog1.mp4", "/videos/dog1_copy.mp4", ]; let hashes: Vec<_> = videos .into_iter() .filter_map(|p| builder.hash(PathBuf::from(p)).ok()) .collect(); let groups = search(hashes, DEFAULT_SEARCH_TOLERANCE); // Process each duplicate group for (idx, group) in groups.iter().enumerate() { println!("Group {}:", idx + 1); // Get number of duplicates in group println!(" Total duplicates: {}", group.len()); // Check if this group has a reference video if let Some(reference) = group.reference() { println!(" Reference: {}", reference.display()); } else { println!(" No reference (self-search)"); } // Iterate over duplicate paths println!(" Duplicates:"); for dup_path in group.duplicates() { println!(" - {}", dup_path.display()); } // Get all paths (reference + duplicates) println!(" All paths in group:"); for path in group.contained_paths() { println!(" - {}", path.display()); } } // Example: Find and delete duplicates, keeping smallest files for group in &groups { let paths: Vec<&Path> = group.duplicates().collect(); // Find largest file in group (you might keep smallest instead) let mut largest_size = 0u64; let mut largest_path: Option<&Path> = None; for path in &paths { if let Ok(metadata) = std::fs::metadata(path) { let size = metadata.len(); if size > largest_size { largest_size = size; largest_path = Some(path); } } } if let Some(keep_path) = largest_path { println!("\nWould keep: {}", keep_path.display()); for path in paths { if path != keep_path { println!(" Would delete: {}", path.display()); // std::fs::remove_file(path)?; // Uncomment to actually delete } } } } // Get all pairwise combinations of duplicates println!("\nPairwise combinations:"); for group in &groups { let combinations = group.dup_combinations(); for combo in combinations { println!("Pair:"); for path in combo.duplicates() { println!(" - {}", path.display()); } } } Ok(()) } ``` -------------------------------- ### Launch GUI Mode for Video Duplicate Review (Linux Only) Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Launches a graphical user interface (GUI) on Linux systems for visually examining and managing duplicate videos. The GUI provides features for previewing videos, marking them for deletion, and navigating through duplicate groups. ```bash # Start GUI to review duplicates vid_dup_finder --files /path/to/videos --gui # GUI allows you to: # - Preview video files side-by-side # - Mark videos for deletion # - View video properties # - Navigate through duplicate groups ``` -------------------------------- ### Create Video Hashes with Default Options (Rust) Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Demonstrates how to create perceptual hashes for video files using the `VideoHashBuilder` with default settings. It shows how to hash a single video and multiple videos, returning `VideoHash` objects containing the source path and duration. Requires the `vid_dup_finder_lib` crate. ```rust use vid_dup_finder_lib::{VideoHashBuilder, VideoHash}; use std::path::PathBuf; fn main() -> Result<(), Box> { // Create hash builder with default options let builder = VideoHashBuilder::default(); // Hash a single video file let video_path = PathBuf::from("/path/to/video.mp4"); let hash = builder.hash(video_path)?; // Hash multiple videos let videos = vec![ PathBuf::from("/videos/cat_video_1.mp4"), PathBuf::from("/videos/cat_video_2.webm"), PathBuf::from("/videos/dog_video.mp4"), ]; let hashes: Result, _> = videos .into_iter() .map(|path| builder.hash(path)) .collect(); match hashes { Ok(video_hashes) => { println!("Successfully created {} hashes", video_hashes.len()); for hash in &video_hashes { println!(" - {} (duration: {}s)", hash.src_path().display(), hash.duration() ); } Ok(()) } Err(e) => { eprintln!("Failed to create hash: {}", e); Err(e.into()) } } } ``` -------------------------------- ### Rust: Generate Video Hashes and Compute Hamming Distance Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt This snippet shows how to generate video hashes using `VideoHashBuilder`, access properties like source path and duration, and compute the Hamming distance between two hashes. It also includes logic to interpret the distance for identifying duplicate or similar videos and demonstrates creating a distance matrix for multiple videos. Dependencies include the `vid_dup_finder_lib` crate. ```rust use vid_dup_finder_lib::{VideoHashBuilder, VideoHash}; use std::path::PathBuf; fn main() -> Result<(), Box> { let builder = VideoHashBuilder::default(); let video1 = PathBuf::from("/videos/original.mp4"); let video2 = PathBuf::from("/videos/copy.mp4"); let hash1 = builder.hash(video1)?; let hash2 = builder.hash(video2)?; // Access hash properties println!("Video 1:"); println!(" Path: {}", hash1.src_path().display()); println!(" Duration: {} seconds", hash1.duration()); println!("\nVideo 2:"); println!(" Path: {}", hash2.src_path().display()); println!(" Duration: {} seconds", hash2.duration()); // Compute hamming distance between hashes let distance = hash1.hamming_distance(&hash2); println!("\nHamming distance: {}", distance); // Interpret distance (lower = more similar) // Distance of 0 = identical hashes // Distance < ~350 (tolerance 0.35 * 1000) = likely duplicates // Distance > 500 = probably different videos if distance == 0 { println!("Videos are identical"); } else if distance < 350 { println!("Videos are very similar (likely duplicates)"); } else if distance < 500 { println!("Videos have some similarity"); } else { println!("Videos are different"); } // Compare multiple videos let videos = vec![ "/videos/cat1.mp4", "/videos/cat2.mp4", "/videos/cat3.mp4", ]; let hashes: Vec = videos .into_iter() .filter_map(|p| builder.hash(PathBuf::from(p)).ok()) .collect(); // Create distance matrix println!("\nDistance matrix:"); for (i, hash_i) in hashes.iter().enumerate() { for (j, hash_j) in hashes.iter().enumerate() { if i < j { let dist = hash_i.hamming_distance(hash_j); println!(" Video {} <-> Video {}: {}", i+1, j+1, dist); } } } Ok(()) } ``` -------------------------------- ### Search for Duplicate Videos with Reference Directory Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Finds videos in a specified directory that are duplicates of videos present in a reference directory. It takes the directory containing new videos and the reference directory as input. The output lists the reference file and its corresponding duplicates found in the new videos directory. ```bash # Find videos in 'new_videos' that are duplicates of videos in 'originals' vid_dup_finder --files /path/to/new_videos --with-refs /path/to/originals # Example output: # Reference: /path/to/originals/vacation.mp4 # Duplicates: # /path/to/new_videos/vacation_copy.mp4 # /path/to/new_videos/vacation_compressed.webm ``` -------------------------------- ### Configure Crop Detection for Video Hashing Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Demonstrates configuring `Cropdetect` options within `CreationOptions` for `VideoHashBuilder`. It shows how to disable crop detection, use letterbox detection for static black bars, and motion detection for dynamic or changing black bars. This affects the fastest method for hashing video frames. ```rust use vid_dup_finder_lib::{VideoHashBuilder, CreationOptions, Cropdetect}; use std::path::PathBuf; fn main() -> Result<(), Box> { // No crop detection - fastest, use raw video frames let no_crop_options = CreationOptions { skip_forward_amount: 0.0, duration: 10.0, cropdetect: Cropdetect::None, }; let no_crop_builder = VideoHashBuilder::from_options(no_crop_options); // Letterbox detection - detects static black bars (top/bottom/left/right) // Use for movies that have consistent black bars let letterbox_options = CreationOptions { skip_forward_amount: 15.0, duration: 10.0, cropdetect: Cropdetect::Letterbox, }; let letterbox_builder = VideoHashBuilder::from_options(letterbox_options); // Motion detection - detects regions with no motion // Use for videos where black bars may move or change let motion_options = CreationOptions { skip_forward_amount: 15.0, duration: 10.0, cropdetect: Cropdetect::Motion, }; let motion_builder = VideoHashBuilder::from_options(motion_options); let video = PathBuf::from("/videos/widescreen_movie.mp4"); // Try different detection methods let hash_no_crop = no_crop_builder.hash(video.clone())?; println!("No crop: hamming distance baseline"); let hash_letterbox = letterbox_builder.hash(video.clone())?; let distance = hash_no_crop.hamming_distance(&hash_letterbox); println!("Letterbox vs no crop: distance = {}", distance); let hash_motion = motion_builder.hash(video)?; let distance2 = hash_letterbox.hamming_distance(&hash_motion); println!("Motion vs letterbox: distance = {}", distance2); // Letterbox detection typically works best for most use cases // Motion detection may help with complex videos but is slower Ok(()) } ``` -------------------------------- ### Handle Video Hashing Errors with Rust Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt This Rust code shows how to handle potential errors when creating video hashes using `VideoHashBuilder`. It iterates through a list of test file paths, attempts to hash them, and prints specific error messages for cases like non-video files, insufficient frames, or general video processing issues. It uses a `match` statement to differentiate between various `Error` variants. ```rust use vid_dup_finder_lib::{VideoHashBuilder, Error}; use std::path::PathBuf; fn main() { let builder = VideoHashBuilder::default(); let test_files = vec![ "/videos/normal.mp4", "/videos/not_a_video.txt", "/videos/too_short.mp4", "/videos/corrupted.mp4", "/nonexistent/file.mp4", ]; for file_path in test_files { let path = PathBuf::from(file_path); match builder.hash(path.clone()) { Ok(hash) => { println!("Success: {} (duration: {}s)", hash.src_path().display(), hash.duration() ); } Err(Error::NotVideo) => { eprintln!("Error: {} is not a valid video file", path.display()); } Err(Error::NotEnoughFrames) => { eprintln!("Error: {} is too short or has no video frames", path.display()); } Err(Error::VidProc(msg)) => { eprintln!("Error processing {}: {}", path.display(), msg); } } } } ``` -------------------------------- ### Adjust Duplicate Search Sensitivity with Custom Tolerance Source: https://context7.com/farmadupe/vid_dup_finder_lib/llms.txt Enables adjustment of the search sensitivity using custom tolerance values. Lower tolerance values result in stricter matching (fewer false positives), while higher values are more lenient (finding more potential duplicates). ```bash # Use stricter tolerance (fewer false positives) vid_dup_finder --files /videos --tolerance 0.2 # Use more lenient tolerance (find more potential duplicates) vid_dup_finder --files /videos --tolerance 0.5 ```