Skip to content

nazimcanislam/shrinkify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

62 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Shrinkify icon

Shrinkify

Analyze media files, suggest codec conversions, detect duplicates, and generate a detailed HTML report.

Python ffmpeg exiftool Platform License GitHub Sponsors

Built in collaboration with Claude (Anthropic). This project was designed and developed through an iterative conversation between a human developer and Claude. The architecture, code, and documentation were produced together β€” a genuine human–AI collaboration.


✨ Features

  • πŸ“Š Smart Analysis β€” ffprobe extracts codec, bitrate, resolution, and format for every file
  • πŸ”„ Conversion β€” H.264 β†’ H.265 (ffmpeg), JPEG β†’ AVIF (ffmpeg + exiftool)
  • 🎚️ Quality Presets β€” Maximum Shrink / Balanced / Conservative
  • πŸ“ Complete Output β€” optionally copies unconverted files too, so the output folder is self-contained
  • πŸ” Duplicate Detection β€” hash-based detection and deletion
  • πŸ“„ HTML Report β€” estimated savings, codec distribution charts, per-file tables
  • πŸ–₯️ CLI + GUI β€” terminal and tkinter desktop interface
  • πŸ”’ Metadata Preserved β€” all EXIF metadata (GPS, capture date, camera model, orientation) is fully copied to output files via exiftool
  • ⚠️ Error Resilient β€” files that fail to scan are logged and skipped gracefully

🎡 Note: Shrinkify focuses on photos and videos only. Audio files (MP3, FLAC, AAC, etc.) are not analyzed or converted β€” that's a separate concern better handled by a dedicated tool.


πŸ–₯️ Platform Note

Shrinkify has been tested on Windows. It should work on Linux and macOS as well (Python and ffmpeg are cross-platform), but this has not been verified. Contributions welcome.


⚑ GPU Acceleration

Using the --hw-accel flag enables hardware-accelerated video encoding. Shrinkify automatically detects your GPU and selects the best available encoder:

Hardware Encoder
NVIDIA NVENC (H.265)
Intel Quick Sync (QSV)
AMD AMF
Apple Silicon VideoToolbox

If no compatible GPU is found, it silently falls back to CPU encoding.

Why use GPU acceleration?

  • ⏱️ Much faster encoding β€” GPU encoders are typically 5–10Γ— faster than CPU (libx265) for large video libraries
  • πŸ”‹ Lower power consumption β€” dedicated encoder hardware uses far less energy than running the CPU at full load
  • 🌑️ Less heat β€” your system stays cooler, especially on laptops
  • πŸ–₯️ System stays responsive β€” your CPU is free for other tasks while the GPU handles encoding

The trade-off is a slight reduction in compression efficiency compared to slow CPU presets β€” but for most use cases the speed and power savings are well worth it.

CPU vs GPU β€” what to expect: Hardware encoders are significantly faster but produce larger output files compared to CPU (libx265). In our tests, converting 11,000 files (60 GB) with GPU took around 1–2 hours. The same job with CPU would take many times longer. If maximum compression is your priority, use CPU mode. If you want to process large collections quickly and are happy with good-enough compression, GPU mode is the better choice.

πŸŸ₯ AMD GPU Acceleration

On AMD iGPU (Ryzen APU) users, the hevc_amf encoder may be listed by ffmpeg but may not work due to driver restrictions. Shrinkify automatically detects this and switches to CPU-based libx265 encoding. GPU acceleration generally works on external AMD GPUs.


πŸ“‹ Requirements

  • Python 3.10+
  • ffmpeg + ffprobe (video and image conversion, analysis)
  • exiftool (metadata preservation for image conversion)

Install ffmpeg

Windows (recommended: WinGet)

winget install Gyan.FFmpeg

After installing, restart your terminal so the PATH update takes effect, then verify:

ffprobe -version

⚠️ Common issue: If you installed ffmpeg but Shrinkify still reports it as missing, the bin folder is likely not in your system PATH. WinGet installs ffmpeg to a path like:

C:\Users\<YourName>\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_...\ffmpeg-x.x-full_build\bin

Add this bin folder to your PATH manually via System Properties β†’ Environment Variables β†’ Path β†’ Edit, then restart your terminal and the app.

Windows (manual)

  1. Download the full_build zip from gyan.dev
  2. Extract it and add the bin folder to your system PATH
  3. Verify: open a terminal and run ffprobe -version

⚠️ Windows: If ffmpeg is not found, try running Shrinkify as Administrator (right-click β†’ "Run as administrator"). This is required when ffmpeg is installed system-wide but PATH is not available to the current user session.

macOS

brew install ffmpeg

Linux

sudo apt install ffmpeg      # Debian / Ubuntu
sudo dnf install ffmpeg      # Fedora

Install exiftool

exiftool is required for image conversion. Without it, image conversion is blocked at startup (no CPU is wasted on a conversion that would lose metadata).

Windows (recommended: WinGet)

winget install OliverBetz.ExifTool

Restart your terminal after installing, then verify:

exiftool -ver

Windows (standalone β€” no install needed)

  1. Download the Windows Executable from exiftool.org
  2. Rename exiftool(-k).exe to exiftool.exe
  3. Place it next to gui.py (project root) β€” Shrinkify will find it automatically

macOS

brew install exiftool

Linux

sudo apt install libimage-exiftool-perl   # Debian / Ubuntu
sudo dnf install perl-Image-ExifTool      # Fedora

πŸš€ Usage

GUI

python gui.py

Workflow:

  1. Select a directory
  2. Choose a quality preset (Balanced is recommended)
  3. Optionally enable "Copy originals to output folder" to get a complete self-contained output
  4. Click Analyze β€” scans files, detects duplicates, generates HTML report
  5. Click Convert Files or Delete Duplicates independently
  6. Use Dry Run to preview results without modifying anything

CLI

# Analyze only + HTML report
python cli.py "C:\Photos"

# Analyze + convert (balanced preset)
python cli.py "C:\Takeout" --convert

# Convert + copy unconverted files too (complete output folder)
python cli.py "C:\Takeout" --convert --copy-originals

# Maximum compression
python cli.py "C:\Takeout" --convert --preset max

# Delete duplicates
python cli.py "C:\Media" --duplicates

# Simulate everything without modifying any files
python cli.py "C:\Media" --convert --duplicates --dry-run

# GPU-accelerated video conversion (auto-detects NVIDIA / Intel / AMD / Apple Silicon)
python cli.py "C:\Videos" --convert --hw-accel

CLI Options

Option Description
--convert Convert candidates
--preset <n> max, balanced (default), or conservative
--copy-originals Also copy unconverted files to output folder
--duplicates Delete duplicate files
--dry-run Simulate β€” no files are modified or deleted
--hw-accel GPU-accelerated encoding (auto-detects available hardware)
--no-hash Skip hash computation (faster, no duplicate detection)
--report <file> HTML report filename (default: shrinkify_report.html)
--no-report Skip HTML report generation

🎚️ Quality Presets

Preset Video CRF Image CRF Description
max 28 38 Smallest files. Slight quality reduction, unlikely to be noticeable.
balanced 24 27 Best trade-off. Recommended default.
conservative 20 18 Minimal quality loss. Larger files, safer for archival.

πŸ“‚ Output Folder

Converted files go into shrinkified/ inside the scanned directory, with original filenames preserved. Original files are never modified.

C:\Takeout\
β”œβ”€β”€ photo.jpg            ← original, untouched
β”œβ”€β”€ video.mp4            ← original, untouched
└── shrinkified\
    β”œβ”€β”€ photo.avif       ← converted (AVIF, all metadata preserved)
    └── video.mp4        ← converted (H.265)

With "Copy originals" enabled, unconverted files are also copied into shrinkified/, giving you a complete folder you can use as a drop-in replacement.


πŸ”„ Conversion Criteria

Source Target Engine Est. Savings (balanced)
H.264 (AVC) video H.265 (HEVC) ffmpeg ~55%
MPEG-4, MPEG-2 video H.265 (HEVC) ffmpeg ~55%
JPEG photo AVIF ffmpeg + exiftool ~30–40%
HEVC, AV1 video β€” β€” Not touched
AVIF, HEIF photo β€” β€” Not touched
Low-bitrate video (<3 Mbps) β€” β€” Skipped (already lean)

πŸ“¦ Distributing as a Standalone Executable

Use PyInstaller to create a single-file executable with no Python dependency.

Install PyInstaller

pip install pyinstaller

Build

Windows

pyinstaller --onefile --windowed --icon=assets/icon.ico --name=Shrinkify gui.py

macOS

pyinstaller --onefile --windowed --icon=assets/icon.png --name=Shrinkify gui.py

Linux

pyinstaller --onefile --name=Shrinkify gui.py

The executable will be in the dist/ folder.

πŸ“Œ ffmpeg, ffprobe, and exiftool are not bundled β€” users must install them separately. For a fully self-contained build, copy all three binaries next to the .exe. Shrinkify automatically searches the directory containing the executable before falling back to PATH.


πŸ—‚οΈ Project Structure

shrinkify/
β”œβ”€β”€ .github/workflows/
β”œβ”€β”€ assets/
β”‚   β”œβ”€β”€ icon.ico
β”‚   └── icon.png
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ scanner.py      # ffprobe analysis + hash/duplicate detection
β”‚   β”œβ”€β”€ analyzer.py     # conversion decision logic + quality presets
β”‚   β”œβ”€β”€ converter.py    # ffmpeg + exiftool conversion pipeline
β”‚   β”œβ”€β”€ reporter.py     # HTML + terminal report
β”‚   └── utils.py        # binary resolution, subprocess helpers
β”œβ”€β”€ docs/
β”‚   └── index.html      # GitHub Pages deployment
β”œβ”€β”€ cli.py              # Command-line interface
β”œβ”€β”€ gui.py              # tkinter GUI
β”œβ”€β”€ version.py
β”œβ”€β”€ CHANGELOG.md
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ .gitignore
└── README.md

πŸ–ΌοΈ AVIF & HEVC Compatibility

Before converting your entire library, check whether your devices can open the output files.

Well-supported βœ…

Platform AVIF photos H.265 video
Windows 10 / 11 βœ… native (Photos app, Edge) βœ… (requires free HEVC Video Extensions)
macOS Ventura (13)+ βœ… native βœ… native
iOS 16+ βœ… native βœ… native
Android 10+ βœ… native βœ… most devices
Modern browsers (Chrome, Firefox, Safari) βœ… βœ…
VLC (all platforms) βœ… βœ…

May have issues ⚠️

Platform Notes
Windows 7 / 8 / 8.1 No native H.265 support; AVIF requires a modern viewer
Android 9 and older Inconsistent β€” depends on manufacturer and hardware decoder
Old Smart TVs (pre-2018) Often no H.265 hardware decoder; AVIF unlikely to be supported
Some older digital photo frames AVIF not supported

πŸ’‘ AVIF is royalty-free and supported natively on all major modern platforms. If you share files with people on older devices, keep the originals or use the Conservative preset. For personal archival use on modern devices (2019+), converting is safe.


πŸ“„ License

MIT


Also available in: πŸ‡ΉπŸ‡· TΓΌrkΓ§e

About

Analyze media files, suggest codec conversions, detect duplicates, and generate a detailed HTML report.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages