This simple program converts all video files from an input
folder and outputs the converted file in an output
folder using HandBrakeCLI.
After successful conversion, the original source file placed into a separated processed
folder to prevent it from getting converted again in the next run.
It's very similar to docker-handbrake
or other tools like unmanic
but without GUI and is made to be as simple as possible.
You can create presets in the Handbrake GUI on Desktop and add these presets to the presets
folder.
Based on which subfolder inside of input
you place your files, a different preset is being used.
It's controlled through a very simple REST API.
It should fit your needs perfectly if you are used to adding hundreds of files to your handbrake queue and want to automate that.
- REST-API
- Fully controllable through the API for better automation
- Supports multiple Handbrake Presets:
- Use all the power of Handbrake
- Temporary filenames:
- Normally it's hard to tell if a handbrake task was finished successfully because the output file looks normal at the first look. Using temporary filenames, you can easily tell if the conversion was successfully finished.
- Stop/Resume batch:
- When stopping the process using the API, it will finish the current file and then stop. On the next start it will resume the rest of the files. NOTE: It's not possible to pause mid-file!
- If interrupted, it leaves behind an unfinished file with the prefix
.tmp_
in the output folder. This file can't be resumed but will be restarted the next time.
- File locking / prevent multiple processes working on the same file
- Make force stop work (need to somehow kill the handbrake command execution for that)
- Docker image + Proxmox LXC template
- Add authentication if this project will ever gets attention and there are users that need it
Endpoint | Description |
---|---|
/api/start |
Starts processing all files in the input folder |
/api/stop |
Finishes the current file and then stops |
/api/stop?force=true |
Interrupts the process immediately. The unfinished file can't be resumed but will be restarted the next time. |
/api/status |
Example output: {"current_file":null,"scheduled_stop":false,"source_files_failed":null,"source_files_processed":null,"source_files_successful":null,"source_files_total":null,"status":"idle"} |
It allows you to very simply automate start/stopping. For example, you can call this API from Home Assistant to start the conversion whenever there's excess solar power. If you want to fully shut down the PC when no conversion is running, you can use Wake on LAN and configure the script to run on startup (using a cronjob or run as systemd service). To shut down the PC, you can use the status endpoint to check if a conversion is currently running.
Example to integrate it into Home Assistant
- Download the
convert.py
file from Releases - Make sure these packages are installed on your system:
handbrake-cli python3-flask python3-waitress
- Manually create a folder structure like this. Currently, it doesn't get automatically generated and the folder names
input
,output
,processed
andpresets
are hardcoded. - Optional: Run as systemd service
- Start the program your preferred way (e.g.
python3 convert.py
). The API is now accessible at:http://x.x.x.x:5000/
- Create a handbrake preset (using Handbrake GUI on your PC) and export it (Preset filename AND preset displayname must match! Currently only one preset per export file is supported!)
- Place your presets into the
presets
folder - Create a sub-folder inside of
input
named exactly the same as your preset - Put your source files into the
input/presetName
folder - To start the conversion, please refer to REST API
You can add as many presets as you want. The corresponding preset will be used for your files depending on which sub-folder inside of input
they are.
By default, the program will idle after startup and wait for a start request.
However, there are some options that you can use. Check them out with python3 convert.py --help
To run the program without leaving the terminal open and automatically on startup, you can create a systemd service.
nano /etc/systemd/system/handbrake-helper.service
- Insert this and adjust
WorkingDirectory
andExecStart
to match your paths:
[Unit]
Description=Handbrake helper
After=network.target
[Service]
ExecStart=/usr/bin/python3 /mnt/convert/convert.py
WorkingDirectory=/mnt/convert
StandardOutput=append:/var/log/handbrake-helper.log
StandardError=append:/var/log/handbrake-helper.err.log
Restart=always
User=user
Group=user
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable handbrake-helper.service
systemctl start handbrake-helper.service
systemctl status handbrake-helper.service
Before conversion:
.
└── convert/
├── input/
│ └── preset1/
│ └── something.S01/
│ ├── something.S01E01.mp4
│ └── something.S01E02.mp4
├── output
├── processed
├── presets/
│ └── preset1.json
└── convert.py
Mid-conversion:
.
└── convert/
├── input/
│ └── preset1/
│ └── something.S01/
│ └── something.S01E02.mp4
├── output/
│ └── something.S01/
│ ├── something.S01E01.mkv
│ └── .tmp_something.S01E02.mkv
├── processed/
│ └── something.S01/
│ └── something.S01E01.mp4
├── presets/
│ └── preset1.json
└── convert.py
After conversion:
.
└── convert/
├── input/
│ └── preset1
├── output/
│ └── something.S01/
│ ├── something.S01E01.mkv
│ └── something.S01E02.mkv
├── processed/
│ └── something.S01/
│ ├── something.S01E01.mp4
│ └── something.S01E02.mp4
├── presets/
│ └── preset1.json
└── convert.py
You can add custom HandBrakeCLI options to the command by creating specifically named files in the input folder. There are 2 options:
- Use a file called
_.hbconf
that applies to all files at the same directory (in the future nested directories might be supported too) - Use a file called exactly like a specific video file with the
.hbconf
extension to only apply the options for a specific file
In this file, you simply write the additional options as plain text.
Example: --chapters 1-5
NOTE: Currently the _.hbconf
file does not work for nested directories! It must be on the same level as your video files.
See the handbrake documentation for all available options: https://handbrake.fr/docs/en/latest/cli/command-line-reference.html
It's possible to use jinja2 templating in the hbconf
file.
For example, if you always want to remove the last chapter: --chapters 1-{{ video.chapter_amount - 1 }}
NOTE: Files with multiple video tracks might cause some issues currently.
Currently supported variables:
Variable | Description |
---|---|
video.chapter_amount | The amount of chapters in the video |
All kind of contributions are very welcome in code and documentation!
Please report bugs if you've found some in Issues
.
For feature requests please use Discussions
.