GitHub

Une version française de ce fichier README est disponible : README_fr.md
A French version of this README is available: README_fr.md

Screenshot of the GUI

Table of Contents

MediaDurationRecursiveChecker

This Python script calculates the total duration of media files (video/audio) in a directory and estimates the total processing time. It was created to help estimate the total duration of daily/rush footage on a hard drive. The project was renamed from FileSizeTreeChecker to MediaDurationRecursiveChecker to better reflect its purpose.

Features

  • Supports common media formats: .mp3, .mp4, .avi, .mkv, .mov, .wav, .flac, .mxf, .raw (case-insensitive)
  • Recursively scans directories
  • Detects and reports duplicate files using SHA256 hashes
  • Excludes hidden files (those starting with '.')
  • Multi-threaded processing (configurable 1-16 threads) for faster performance
  • Minimum file size filtering to skip small files
  • Provides:
    • Total number of media files
    • Total size in GB
    • Total duration of all files with real-time estimation
    • Progress tracking with percentage completion
    • Verbose output with individual file durations
    • Comprehensive results saved to JSON file with detailed metadata
    • Duplicate file detection and grouping
    • Failed file tracking and reporting
    • Skipped file statistics

Requirements

  • Python 3.6+ (only tested on 3.8 and 3.11)
  • moviepy (for media duration extraction)
  • pyperclip (to handle copying and pasting the path)
  • loguru (to logs)
  • If possible, ffmpeg is used as a fallback.

Installation and Usage

You have three options to run MediaDurationRecursiveChecker:

1. Download Pre-built App (Recommended)

Pre-compiled .app bundles for macOS (both Intel and Apple Silicon) are built automatically using GitHub Actions and are available in the builds/ folder in this repository. Just download the zip for your architecture and extract it.

Warning

macOS Gatekeeper notice: Since this app is not signed with an Apple Developer certificate, macOS will block it on first launch. You will see: "MediaDurationRecursiveChecker" can't be opened because Apple cannot check it for malicious software.

To allow it:

  1. Open System Settings > Privacy & Security
  2. Scroll down to find the message "MediaDurationRecursiveChecker" was blocked from use because it is not from an identified developer
  3. Click "Open Anyway"
  4. On the final confirmation dialog, click "Open"

This is a one-time step. These Gatekeeper prompts are standard on macOS Ventura (13) and later.

2. Run from Source

  1. Install required Python packages:
# Basic installation (all platforms):
pip install -r requirements.txt
# Platform-specific installation:
# For macOS:
pip install -r requirements-macos.txt
# For Linux:
pip install -r requirements-linux.txt
# For Windows:
pip install -r requirements-windows.txt
# For development:
pip install -r requirements-dev.txt
  1. Ensure ffmpeg is installed on your system
  2. Run the script:
python MediaDurationRecursiveChecker.py
  1. Use the graphical interface to select folders and process files

3. Build Your Own Executable

If you prefer to build it yourself:

  1. Install PyInstaller:
pip install pyinstaller
  1. Build the executable:

macOS (matches the CI build used to produce the pre-built releases):

pyinstaller \
  --onefile \
  --windowed \
  --name MediaDurationRecursiveChecker \
  --hidden-import=imageio_ffmpeg \
  --copy-metadata imageio \
  --clean \
  MediaDurationRecursiveChecker.py

Other platforms (Linux / Windows):

pyinstaller --onefile --name MediaDurationRecursiveChecker --hidden-import=imageio_ffmpeg --copy-metadata imageio --clean MediaDurationRecursiveChecker.py
  1. The executable will be in the dist directory

Output Example

Found 1234 media files (456.78 GB)
Processing files: 100%|████████████████████| 1234/1234 [12:34<00:00,  1.23it/s]
Current: 12h 34m | Estimated total: 15h 30m
Total duration: 15h 30m
Results saved to media_durations.json

JSON Output Format

The output JSON file contains comprehensive information:

{
  "summary": {
    "total_files": 1234,
    "processed_files": 1200,
    "skipped_files": 34,
    "min_file_size_kb": 100,
    "total_size_gb": 456.78,
    "total_duration_seconds": 55800,
    "total_duration_readable": "15h 30m",
    "failed_files_count": 5,
    "duplicate_groups_count": 3,
    "total_duplicate_files": 8
  },
  "files": {
    "/path/to/file.mp4": {
      "duration": 3600,  // in seconds
      "size": 1048576,   // in bytes
      "hash": "sha256_hash_here"
    }
  },
  "duplicate_groups": [
    ["/path/to/file1.mp4", "/path/to/duplicate1.mp4"],
    ["/path/to/file2.avi", "/path/to/duplicate2.avi"]
  ],
  "failed_files": [
    "/path/to/corrupted_file.mp4"
  ]
}

Notes

  • Files are processed in random order to provide better time estimates
  • The script handles errors gracefully, skipping files it can't process
  • Duplicate detection uses SHA256 hashes for accurate identification
  • Multi-threading significantly improves processing speed on modern systems
  • Skipped files (below minimum size) are tracked separately and don't affect duration calculations

Read the original on github.com ↗