An automated video encoding system that watches a folder for video files and encodes them using HandBrakeCLI with the "Very Fast 720p30" preset.
- Automatic File Detection: Watches the
inputfolder for new video files - Fast Encoding: Uses HandBrake's "Very Fast 720p30" preset for quick processing
- Real-Time Progress Display: Visual progress bar with percentage and ETA during encoding
- File Management: Automatically moves original files to
donefolder after encoding - Comprehensive Logging: Logs all activities to both console and log files
- File Stability Check: Waits for files to be completely copied before processing
- Multiple Format Support: Supports common video formats (MP4, AVI, MKV, MOV, etc.)
handbrake/
├── input/ # Drop video files here
├── output/ # Encoded files will be saved here
├── done/ # Original files moved here after encoding
├── logs/ # Log files
├── venv/ # Python virtual environment (auto-created)
├── handbrake_watcher.py # Main script
├── requirements.txt # Python dependencies
├── config.ini # Configuration file
├── config.ini.example # Example configuration
├── setup_mac.sh # Setup script (macOS/Linux)
├── setup.bat # Setup script (Windows Command Prompt)
├── setup.ps1 # Setup script (Windows PowerShell)
├── start_watcher_mac.sh # Launcher script (macOS/Linux)
├── start_watcher.bat # Launcher script (Windows Command Prompt)
└── start_watcher.ps1 # Launcher script (Windows PowerShell)
└── start_watcher.ps1 # Launcher script (Windows PowerShell)
- Python 3.6+
- HandBrakeCLI: The command-line version of HandBrake
- watchdog: Python library for file system monitoring (auto-installed by setup script)
./setup_mac.shsetup.bat.\setup.ps1Note for PowerShell users: If you get an execution policy error, run this first:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserThis will:
- Create a Python virtual environment
- Install all dependencies
- Verify HandBrake CLI installation
- Create required directories (input, output, done, logs)
- Make scripts executable (macOS/Linux)
-
Install HandBrakeCLI:
macOS:
brew install handbrake
Windows:
- Download from: https://handbrake.fr/downloads.php
- Or use Chocolatey:
choco install handbrake - Or use Winget:
winget install HandBrake.HandBrake
Linux:
# Ubuntu/Debian sudo apt install handbrake-cli # Or download from: https://handbrake.fr/downloads.php
-
Create virtual environment and install dependencies:
macOS/Linux:
python3 -m venv venv source venv/bin/activate pip install -r requirements.txtWindows (Command Prompt):
python -m venv venv venv\Scripts\activate.bat pip install -r requirements.txt
Windows (PowerShell):
python -m venv venv .\venv\Scripts\Activate.ps1 pip install -r requirements.txt
-
Start the folder watcher:
macOS/Linux:
# Easiest method ./start_watcher_mac.sh # Or manually source venv/bin/activate python handbrake_watcher.py
Windows (Command Prompt):
REM Easiest method start_watcher.bat REM Or manually venv\Scripts\activate.bat python handbrake_watcher.py
Windows (PowerShell):
# Easiest method .\start_watcher.ps1 # Or manually .\venv\Scripts\Activate.ps1 python handbrake_watcher.py
-
Drop video files into the
inputdirectory -
Watch real-time progress in the console:
🔧 Checking directories... ✅ Created Input directory: /Users/username/handbrake/input ✅ Output directory: /Users/username/handbrake/output ✅ Done directory: /Users/username/handbrake/done ============================================================ 🎬 Encoding: my_video.mp4 ============================================================ 📊 Progress: [████████████████████░░░░░░░░░░░░░░░░░░░░] 52.3% | ETA: 00h02m15s -
Find encoded files in the
outputdirectory -
Original files are moved to the
donedirectory after successful encoding
The script can be customized using the config.ini file. If the file doesn't exist, the script will use default values and create directories in the default locations.
Note: The script automatically creates the configured directories (input, output, done, logs) if they don't exist, including any parent directories needed for custom paths.
-
Copy the example configuration:
cp config.ini.example config.ini
-
Edit
config.inito customize settings
Directories:
input_dir- Where to watch for new video files (default:input)output_dir- Where encoded files will be saved (default:output)done_dir- Where original files are moved after encoding (default:done)log_dir- Where log files are stored (default:logs)
All paths can be relative (to the script location) or absolute. The script will automatically create these directories if they don't exist, including any necessary parent directories.
Encoding:
preset- HandBrake preset to use (default:Very Fast 720p30)
File Handling:
video_extensions- File extensions to watch (default:.mp4,.avi,.mkv,.mov,.wmv,.flv,.webm,.m4v,.mpg,.mpeg)stabilization_time- Seconds to wait for file stability (default:3)stabilization_check_interval- Seconds between stability checks (default:1)
Logging:
log_level- Logging verbosity:DEBUG,INFO,WARNING,ERROR,CRITICAL(default:INFO)
[Directories]
# Use custom absolute paths
input_dir = /Users/username/Videos/ToEncode
output_dir = /Users/username/Videos/Encoded
done_dir = /Users/username/Videos/Archive
[Encoding]
# Use higher quality preset
preset = Fast 1080p30
[FileHandling]
# Only watch for MP4 and MOV files
video_extensions = .mp4,.mov
# Wait longer for large files
stabilization_time = 5To see all available presets, run:
HandBrakeCLI --preset-listSome popular fast presets:
- "Very Fast 720p30" (default)
- "Very Fast 480p30"
- "Very Fast 1080p30"
- "Fast 720p30"
- MP4
- AVI
- MKV
- MOV
- WMV
- FLV
- WebM
- M4V
- MPG/MPEG
Make sure HandBrake CLI is installed and available in your PATH:
which HandBrakeCLI
HandBrakeCLI --versionThe executable permissions are stored in git and should work after cloning. If needed:
chmod +x setup_mac.sh start_watcher_mac.sh handbrake_watcher.pyIf you get "cannot be loaded because running scripts is disabled" error:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserThis is a one-time setting that allows locally-created scripts to run.
Check the logs for detailed error messages:
tail -f logs/handbrake_watcher.logPress Ctrl+C to stop the folder watcher gracefully.
- File stability check: Waits for files to be completely copied before processing
- Duplicate processing prevention: Avoids processing the same file multiple times
- Error handling: Graceful error handling with detailed logging
- Original file preservation: Original files are only moved after successful encoding
2025-11-04 12:01:39 - INFO - Starting HandBrake Folder Watcher
2025-11-04 12:01:39 - INFO - Input directory: /Users/mdeeter/GIT/handbrake/input
2025-11-04 12:01:39 - INFO - Output directory: /Users/mdeeter/GIT/handbrake/output
2025-11-04 12:01:39 - INFO - Done directory: /Users/mdeeter/GIT/handbrake/done
2025-11-04 12:01:39 - INFO - HandBrakeCLI found: HandBrake 1.10.2
2025-11-04 12:01:39 - INFO - Watching for video files in: /Users/mdeeter/GIT/handbrake/input
2025-11-04 12:01:39 - INFO - Drop video files into the input directory to start encoding...
============================================================
🎬 Encoding: sample_video.mp4
============================================================
📊 Progress: [████████████████████████████████████████] 100.0% | ETA: 00h00m00s
✅ Encoding completed successfully!
📁 Original moved to: sample_video.mp4
📤 Encoded file: sample_video_encoded.mp4
============================================================
The script now shows live encoding progress with:
- Visual Progress Bar: Animated bar that fills as encoding progresses
- Percentage Complete: Real-time percentage (updates every 1%)
- Estimated Time: Shows remaining time (ETA) based on HandBrake calculations
- Status Indicators: Emoji-based status messages for quick recognition
- 🎬 Starting encoding
- 📊 Encoding in progress
- ✅ Successfully completed
- ❌ Failed encoding
- 📁 Original file moved
- 📤 Encoded file ready