In your homelab, you may have some sort of media server which serve video to different devices like Plex, Emby and Jellyfin. While it can transcode to support codec real time, it brings heavy loads to server. By transcoding video in advance, you can lower server load and provide better quality.
One of popular way is to use FFmpeg but there are many parameters to configure, especially you have more than 1 tracks in the source file. Handbrake provide a user friendly GUI on top of FFmpeg and provide presets for simple encoding. You can also customize preset and track selection behavior, so you can apply it to multiple files.
However, because of Handbrake is using GUI, you may not able to run it on your server if you only have terminal access. Someone has create a Docker image which redirects handbrake GUI to a web canvas. Now we can encoding video on the server instead.
Getting Started
Before you continue, make sure you know the followings:
- Docker & Docker Compose
- Handbrake
Here is the simple docker-compose.yml
.
version: "3"
services:
web:
image: jlesage/handbrake
volumes:
- /docker/handbrake/output:/output
- /docker/handbrake/storage:/storage:ro
ports:
- 5800:5800
/storage
is the default folder for Open Source
and /output
is the default folder for output.
After running docker-compose up -d
, you can to to http://<server-ip>:5800
. You should able to see the following screen.
Then, you can use Handbrake normally.
SubStation Alpha / Advanced SubStation Alpha
I have faced some problems when I try to burn-in SubStation Alpha (.ssa
) or Advanced SubStation Alpha (.ass
) subtitle. Here are the problems and solutions.
Thicker border
The encoding video with burn-in subtitles has thicker border than playing with video player like VLC. I opened an issue in the past and found out it was caused by libass. Media players that use VSFilter default ScaledBorderAndShadow
is no
while libass default ScaledBorderAndShadow
is yes
.
To solve this problem, you can add ScaledBorderAndShadow: no
under [Script Info]
to the subtitle file if it does not have one. If the subtitle files is embedded in MKV file, you can use mkvextract to extract the subtitle track.
Using custom font
Those subtitle files often uses custom font which does not exists in the Docker image. You need to mount it to the Docker container.
version: "3"
services:
web:
image: jlesage/handbrake
volumes:
- /docker/handbrake/output:/output
- /docker/handbrake/storage:/storage:ro
- /docker/handbrake/fonts:/usr/share/fonts/custom:ro
- /docker/handbrake/99-font.sh:/etc/cont-init.d/99-font.sh:ro
ports:
- 5800:5800
#!/usr/bin/with-contenv sh
fc-cache -fv
New docker-compose.yml
now mount two more volumes. You can mount your fonts folder to /usr/share/fonts
.
jlesage/handbrake
is using s6-overlay. 99-font.sh
is a script that run when the container start. It rebuilds the font cache. You should able to see the following log if it is loaded.
/usr/share/fonts/custom: caching, new cache contents: 1378 fonts, 0 dirs
Then, you can use Handbrake normally.
Not using correct font
When I was searching for issues, I found someone mention libass does not select unicode font name correctly (I did not face this problem). You can try fc-match <font name>
to get the postfix font name and replace the one in the subtitle file.
You can also see Handbrake log to see if it uses the correct font.
[06:49:13] [ass] fontselect: (MS Gothic, 700, 0) -> /usr/share/fonts/custom/MSGOTHIC.TTC, 0, MS-Gothic