Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Medinox

A collection of portable scripts for managing, standardizing, and repairing a large media library.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Prerequisites

  • Python 3.6+
  • FFmpeg & FFprobe β€” Must be installed and available on PATH.
    brew install ffmpeg

Folder Structure

Medinox/
  catalog/    ← Read-only discovery & reporting (e.g. Master Dashboard)
  organize/   ← File naming, metadata, merging split parts
  process/    ← Active media transformation
  utils/      ← Shared utilities (logger, ffprobe, constants, scoring, filesystem)
  config/     ← Configuration files for library paths
  output/     ← All generated reports, dashboards, logs, and state

High-Performance Parallel Execution

Medinox features an intelligent multi-threading system (utils/system.py) that accelerates scanning and transformation.

  • Hardware-Aware: Automatically detects if the target directory is on a Solid State Drive (SSD) or a mechanical Hard Disk Drive (HDD) on macOS.
  • I/O Protection: Dynamically throttles parallel workers down to 2 concurrent threads for HDDs to prevent catastrophic disk I/O thrashing, while fully unlocking thread limits for fast NVMe/SSDs (up to 16 threads).
  • Timeouts & Safety: Built-in 5-second timeouts for drive detection and 30-second timeouts for ffprobe to ensure scripts never hang indefinitely on sleeping or corrupted drives.
  • Thread-Safe: Uses threading.Lock for all log file I/O and history file writes to prevent data corruption under parallel execution.

Centralized Logging & Progress

All scripts utilize a unified MediaLogger utility (utils/logger.py):

  • Dynamic Progress Bars: Visually track the scan and processing percentage in real time.
  • Execution Summaries: Clean, formatted blocks outputting total files processed, total time taken, and the exact paths to generated CSV/HTML/Log artifacts.
  • Log Rotation: Daily rolling console logs are automatically captured in output/logs/.

Safety Model β€” Dry Run by Default

Every destructive script defaults to a safe dry-run. No files are modified unless you pass the activation flag:

Script Activation Flag What it Does
organize/standardize.py --rename <csv> Applies renames from a CSV plan
process/embed_subtitles.py --apply Embeds SRT files into containers
process/extract_subtitles.py --apply Extracts embedded subs to .srt files
process/strip_subtitles.py --apply Removes subtitle tracks
process/integrity_check.py --apply Runs scan or repair for real
process/transcode.py --apply Transcodes AVC files to HEVC or AV1
process/convert_container.py --apply Remuxes to preferred containers losslessly
organize/tag_metadata.py --apply Writes metadata tags to files
organize/merge_parts.py --apply Performs the actual merge
catalog/find_duplicates.py --delete Trashes lower-quality duplicates

File & Directory Support

Most scripts accept both a single file and a directory:

Script File Directory
process/embed_subtitles.py βœ… βœ…
process/extract_subtitles.py βœ… βœ…
process/strip_subtitles.py βœ… βœ…
process/integrity_check.py βœ… βœ…
process/transcode.py βœ… βœ…
process/convert_container.py βœ… βœ…
organize/tag_metadata.py βœ… βœ…
All catalog/ scripts β€” βœ… (library-wide)
organize/standardize.py β€” βœ…
organize/merge_parts.py β€” βœ… (split folder)

File Processing Order

All scripts process files in case-insensitive alphabetical order (matching macOS Finder sort).

Resolution Logic (Pixel-Based)

Consistent tagging across Ultrawide, IMAX, and Open Matte content:

Category Threshold (Total Pixels) Tag
4K > 6,000,000 4K
1080p 1,500,000 – 6,000,000 1080p
720p 650,000 – 1,500,000 720p
Other < 650,000 Actual height (e.g. 480p)

Timestamp Preservation

All scripts that modify files preserve the original atime/mtime to keep Finder sort order intact.


catalog/ β€” Discovery & Reporting

catalog/build_dashboard.py

Orchestrator script that generates the Master Media Dashboard. It reads paths from config/catalog_jobs.csv.

  • Outputs: output/dashboard/index.html, output/dashboard/Catalog.xlsx, and individual runs in output/dashboard/latest/.

catalog/catalog.py

Generates an interactive HTML dashboard and CSV report of the media library.

  • Usage: python3 Medinox/catalog/catalog.py /path/to/movies [/path/to/more ...]
  • Features: Deep HDR10+/Dolby Vision/HLG detection, sortable table, multi-folder support.
  • Outputs: output/reports/media_catalog_<ts>.html and .csv

catalog/health_check.py

Single-command library audit β€” a "what still needs work" report.

  • Usage: python3 Medinox/catalog/health_check.py /path/to/movies [/path/to/more ...]
  • Checks: Missing subtitles, AVC codec, non-standard names, low resolution, legacy containers, missing audio, unreadable files.
  • Output: Console summary + output/reports/health_check_<ts>.csv & .html
  • Read-only: Never modifies any files.

catalog/find_duplicates.py

Detects duplicate movies by fuzzy title+year matching and recommends which to keep.

  • Usage: python3 Medinox/catalog/find_duplicates.py /path/to/movies [/path/to/more ...] [--delete]
  • Matching: Normalizes titles (strips junk tags, punctuation) then groups by title+year.
  • Scoring: Resolution, bitrate, codec efficiency, bit depth, audio, subtitle presence.
  • --delete: Moves lower-quality duplicates to Trash (macOS only).
  • Output: output/reports/duplicates_<ts>.csv

catalog/compare.py

Compares two video files and calculates a quality score.

  • Usage: python3 Medinox/catalog/compare.py file1.mkv file2.mp4
  • Scoring: Pixel count, bitrate, codec efficiency (AV1 > HEVC > AVC), HDR bonus, audio channels.

organize/ β€” Naming, Metadata & Merging

organize/standardize.py

Renames files to a clean standardized format based on technical metadata.

  • Output Format: Title (Year).Resolution.V_Codec.HDR.A_Codec.A_Channels.ext
    • HDR tag omitted for SDR. Example: Inception (2010).4K.HEVC.HDR10.AAC.5.1.mkv
  • Workflow:
    1. python3 Medinox/organize/standardize.py /path/to/movies β†’ generates output/reports/rename_plan_<ts>.csv
    2. Review and edit the CSV
    3. python3 Medinox/organize/standardize.py --rename <csv>
  • Rollback: python3 Medinox/organize/standardize.py --rollback <csv>

organize/tag_metadata.py

Writes technical info into the video's internal Title and Comment tags.

  • Usage: python3 Medinox/organize/tag_metadata.py <file_or_dir> [--apply]
  • Tag Format: 4K | HEVC | HDR10 5.1 | 45.2Mbps
  • Detects: Dolby Vision via DOVI configuration records.

organize/find_splits.py

Scans for movies split into multiple parts (CD1, CD2, Disc 1, etc.).

  • Usage: python3 Medinox/organize/find_splits.py /path/to/movies
  • Note: Only matches strict CD/Disc/Disk patterns.

organize/verify_splits.py

Checks that all parts have identical stream configurations before merging.

  • Usage: python3 Medinox/organize/verify_splits.py /path/to/split_folder

organize/merge_parts.py

Merges split parts into a single file.

  • Usage: python3 Medinox/organize/merge_parts.py /path/to/split_folder [--apply] [--reencode]
  • Fast-concat: Lossless stream copy (requires identical stream configs).
  • Re-encode (--reencode): Scales to highest resolution, encodes H.264 + AAC 192k. Auto-triggered on resolution mismatch.
  • Output: <parent_dir>/<folder_name>_merged.<ext>

process/ β€” Active Media Processing

process/convert_container.py

Lossless remux between containers (e.g., .avi β†’ .mkv, .ts β†’ .mp4) without re-encoding.

  • Usage: python3 Medinox/process/convert_container.py <file_or_dir> [--apply]
  • Supported Maps: .avi, .wmv to .mkv; .ts, .flv, .mov, .m4v to .mp4.
  • Safety: Original moved to macOS Trash (via Finder) after successful conversion.
  • Deduplication: History file at output/history/container_convert_history.txt.

process/transcode.py

Transcodes AVC (H.264) files to a more efficient codec to save disk space.

  • Usage: python3 Medinox/process/transcode.py <file_or_dir> [--codec hevc|av1] [--apply] [--delete] [--cpu]
  • Codecs:
    • hevc (default) β€” ~40–50% smaller. Universal compatibility.
    • av1 β€” ~50–60% smaller. Best efficiency, limited device support.
  • Hardware Acceleration: Auto-detects VideoToolbox on macOS for fast HEVC encoding. Use --cpu to force software encoding for maximum quality.
  • Encoders: hevc_videotoolbox (HW), libx265 (CPU), libsvtav1 (AV1).
  • Output: Creates <name>.hevc.mkv or <name>.av1.mkv alongside the original.
  • --delete: Trashes the original after successful conversion. Use with caution.

process/integrity_check.py

Scans for corruption and repairs broken container indices.

  • Usage: python3 Medinox/process/integrity_check.py <file_or_dir> [--mode scan|deep|repair] [--apply]
  • Modes: scan (quick, first 5s), deep (full decode), repair (lossless remux).
  • Repair Safety: Verifies output is β‰₯ 90% original size before replacing.

process/embed_subtitles.py

Embeds external .srt files into video containers.

  • Usage: python3 Medinox/process/embed_subtitles.py <file_or_dir> [--apply]
  • SRT matching: Looks for <same_name>.srt next to the video file.
  • Safety: Includes a strict 5MB size limit to reject falsely named video files and prevent memory lockups.
  • Encoding support: Auto-detects UTF-8, UTF-16, UTF-8 BOM, Latin-1, CP1252, ISO-8859-1.
  • Timestamp repair: Fixes missing ms, periodβ†’comma, single-digit hours, re-indexes cues.
  • Deduplication: History file at output/history/subtitles_merge_history.txt.
  • SRT cleanup: Trashes SRT after merge (macOS, via Finder) β€” only if video had 0 existing subs.
  • Container handling: .avi β†’ .mkv; MP4 uses mov_text, all others use srt codec.

process/extract_subtitles.py

Extracts embedded subtitle tracks to external .srt files.

  • Usage: python3 Medinox/process/extract_subtitles.py <file_or_dir> [--apply]
  • Language tagging: Outputs Movie.eng.srt, Movie.fre.srt, etc. Falls back to track number.
  • Format conversion: Converts ASS/SSA/mov_text/etc. to SRT automatically.
  • Safety: Will not overwrite existing .srt files.
  • Use case: Run before strip_subtitles.py to preserve subtitle data externally.

process/strip_subtitles.py

Removes all embedded subtitle tracks from a video container.

  • Usage: python3 Medinox/process/strip_subtitles.py <file_or_dir> [--apply]
  • Safety: Original moved to macOS Trash (via Finder) before the cleaned file takes its place.
  • Stream mapping: Uses 0:v? 0:a? so files missing video or audio don't cause errors.

Shared Utilities (utils/)

Module Purpose
utils/logger.py Thread-safe MediaLogger with daily log rotation, progress tracking, and summary output
utils/system.py Hardware-aware thread count detection (SSD/HDD) and dependency checks
utils/constants.py Single source of truth for VIDEO_EXTENSIONS and codec maps
utils/ffprobe.py Shared FFprobe wrapper: get_metadata(), detect_hdr(), get_resolution_tag(), get_audio_label()
utils/fs.py Cross-platform safe_trash() β€” uses Finder on macOS, falls back to permanent delete
utils/scoring.py Shared score_file() for quality-based duplicate comparison

Cross-Platform Notes

  • Safe Trash: Scripts that remove originals after processing use utils/fs.py:safe_trash(), which calls Finder on macOS and falls back to permanent delete on other platforms.
  • SSD Detection: utils/system.py uses diskutil on macOS for drive type detection. On other platforms it defaults to conservative HDD threading.

Output Directories

  • output/dashboard/ β€” Master Dashboard, Merged Catalogs (Excel), and Latest Library HTML Reports.
  • output/reports/ β€” Standalone CSV plans, HTML dashboards, health reports.
  • output/history/ β€” Script state & processed file history.
  • output/logs/ β€” FFmpeg debug logs (created on failure, auto-deleted on success).

About

Medinox - The Swiss Army Knife for your Media Files πŸ”΄βš”οΈ. A collection of scripts for managing, standardizing, and repairing a large media library.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages