This post describes my home media setup. Namely, how I rip and encode DVDs that I own using Handbrake, store them on a Raspberry Pi running Plex, and play them on my (Sharp) Roku TV. My encoding settings, media types, and subtitle formats are all chosen to avoid live Transcoding by Plex during playback, and allow reasonably high video quality.
I could never manage to convince my Chromecast to handle multiple audio and subtitle tracks correctly. Plex can handle these without issue, all while avoiding Transcoding if we set everything up correctly.
One aspect of this is subtitle type. It seems that keeping all subtitles as external .srt
files is best, as this allows:
A note on opensubtitles.org: Yes it's possible to get loads of .srt
files for free there. However, they're not guaranteed to have the exact timing that your particular DVD expects. So I personally think it's safest to use the subtitles supplied by the DVD itself.
You'll need: makemkv
and ccextractor
.
I use the makemkv
tool. This pulls everything off of your DVD and wraps it in the .mkv
container type. Nothing is reencoded, so you're getting the content as-is. The movie file itself will also be quite large, usually more than 5gb. It will also almost certainly not be in a Plex-friendly encoding, so once we've extracted the subtitles, we'll use Handbrake to reencode.
We perform this step first instead of jumping straight to Handbrake in order to move past one bottleneck of our pipeline: the IO cost of getting the data off the DVD. The later Handbrake processes will be much faster this way.
Steps:
makemkv
GUI. If you have a DVD in a drive, it will be automatically detected.which ccextractor
in your terminal, and enter this full path in View -> Preferences -> Advanced
. You'll only need to do this once.Make MKV
to save the DVD contents to your computer. This will take about 30 minutes.You'll need: mkvinfo
and mkvextract
, both from the mkvtoolnix
package.
We're looking to create an .srt
file from what's available in the DVD. If we're lucky, it will provide one for us. Otherwise we'll need to do some conversion.
Extraction itself is easy. Let's first identify where the subtitles "are":
mkvinfo the-movie.mvk
mkvinfo
will spit out a lot of information, but let's look for Track type:
subtitles
. We're in luck if we see something like this:
| + Track | + Track number: 9 (track ID for mkvmerge & mkvextract: 8) | + Track UID: 9 | + Track type: subtitles | + Default track flag: 0 | + Lacing flag: 0 | + Codec ID: S_TEXT/UTF8 | + Language: eng
Notice the S_TEXT/UTF8
. This subtitle is already an .srt
, so let's grab it:
> mkvextract tracks the-movie.mkv 8:the-movie.en.srt Extracting track 8 with the CodecID 'S_TEXT/UTF8' to the file 'the-movie.en.srt'. Container format: SRT text subtitles
We can then check the output to see if it's what we expect:
> head the-movie.en.srt 1 00:00:27,044 --> 00:00:31,947 ♪ 2 00:02:57,227 --> 00:02:59,527 EXCUSE ME. 3 00:03:02,099 --> 00:03:05,167
Looks good.
If we found no S_TEXT/UTF8
entries, then we're stuck with VOBSUB, which is an image-based format. If used with Plex, it will force a Transcoding, so we'll convert it first. mkvinfo
would show us something like:
| + Track | + Track number: 6 (track ID for mkvmerge & mkvextract: 5) | + Track UID: 6 | + Track type: subtitles | + Default track flag: 0 | + Lacing flag: 0 | + Codec ID: S_VOBSUB | + Language: eng | + Codec's private data: size 511
> mkvextract tracks the-movie.mkv 5:the-movie.en.sub Extracting track 5 with the CodecID 'S_VOBSUB' to the file 'the-movie.en.sub'. Container format: VobSubs Writing the VobSub index file 'the-movie.en.idx'.
Notice that it produces a .idx
as well. Take both these files and visit subtitletools.com. Upload the files and wait for the conversion to complete. You now have your .srt
! Note that you may have to make minor corrections yourself, where the image-to-text translation software misread the words.
You'll need: Handbrake.
Now for the fun part. Handbrake will take our "lossless" .mkv
file, and with the settings I provide below, will reduce it to between 1gb and 2gb without significant quality loss. Further, its video and audio formats will be what Plex needs to avoid Transcoding.
I choose the H.264 MKV 1080p30
preset as a starting point.
The best way to avoid "fuzziness" in the resulting video is to stay as true as possible to the original data. Respecting the original frame rate has a big effect on this. Then, to increase quality overall, we reduce the RF
and set our encoding speed to Slow
. Leave everything else as the default values.
Audio is where we have to be careful. Here are the golden rules:
or
Since we're going to use external .srt
files only, let's make sure we aren't wasting time with Handbrake's default language scan:
To help Plex, we should set some metadata tags as well. If we don't set at least the title, the movie listing will display quite strangely in your Plex library.
After setting the output file name, we can hit Start
to begin the encoding. This will take about an hour, which is worth it for the quality of video you get at the end. Waiting one hour once is better than rushing it, making mistakes, and needing to repeat the process.
This section assumes you have a Raspberry Pi running Raspbian. You will need to have enabled ssh
access in your settings, and you'll need to know the internal IP address of the Pi (check on your router's admin page). For serving media optimally, it's best if your Pi has a wired connection to your router. It's also assumed that you have an external hard drive for your media. It's not recommended to use the Pi's SD card for storing media.
To install Plex on a Pi, follow the Preparing your Pi for Plex
and Installing
Plex to your Raspberry Pi
sections of this guide. My sections below handle drive permissions, which are often a problem.
Consider also installing htop
. We can then confirm that our Plex server is running as we expect:
Debian is convenient, in that it mounts drives for you as soon as you attach them. Unfortunately, it does so as the pi
user. Our Plex server is running as the plex
user, and needs full access to the drive.
First, let's find out where the drive is mounted. Let's ssh
in:
ssh pi@192.168.0.<YOURPI>
Perform this command, and then attach your drive:
watch -n 1 "dmesg | tail -n 25"
Ah ha. Unmounting is easy: the device should appear in /media/pi/
already for us.
sudo umount /meda/pi/<YOURDEVICE>
Now let's remount it in a way that gives plex
access:
sudo mount /dev/sda1 /media/plex/ -o umask=000
You will have to repeat this process whenever you restart your Raspberry Pi.
Plex likes having your media categories separated. Here is how I split mine:
pi@plexpi /m/plex> pwd /media/plex pi@plexpi /m/plex> tree -L 1 . ├── anime ├── movies ├── music ├── podcasts └── shows
For files with subtitles, I like to give them their own subfolder (e.g. movies/Hero/
) as well, although this isn't strictly necessary.
Within Plex Web, visit Settings
and go here:
Click Add Library
and follow the prompts. Your library for "Movies" would live in /media/plex/movies/
, for example.
Naturally, you can detach the drive from your Pi and copy files to it from your main computer yourself. Or, if you don't want any Plex downtime, you can use scp
to copy over the files you created in Handbrake:
scp Hero.mkv pi@192.168.0.<YOURPI>:/media/plex/movies
As soon as the copy is finished, Plex will detect the change and automatically update your Library. You should copy up your subtitles files in the same way, perhaps putting them in a subfolder with their video. Plex requires that they
have the exact same base name as the video they belong to, along with the language code. In the case of Hero
, this would be Hero.en.srt
for English subtitles.
We're almost there. Once we've confirmed a few final settings, we're free to enjoy our media!
Confirm these settings.
Confirm these settings.
These are settings within the Plex app on your TV.
Quality can be maximum, since you're at home on the same network as the Pi.
To make sure Plex doesn't get to excited and burn-in your subtitles even when it doesn't have to, we make sure this is set:
And that's it! Hopefully this guide will help you set up Plex and get media onto it efficiently, so that you, your friends, and your family can benefit from it.
I highly recommend getting a Plex Pass as well. The two biggest features that it unlocks for me are Media Downloading to your devices and a Dashboard that you can access in Plex Web, so that you don't need to ssh
into your PR to monitor its health.
Happy streaming!
Direct Play invokes essentially no CPU overhead, which is why all my settings above optimize for that. However, if something must be transcoded, my Raspberry Pi 4 (4 CPUs, 4gb RAM) can reliably handle one video at a time without any issues (buffering, etc.) on the client end.
It seems everyone who runs a Plex Server hits this mystery. If you've followed my guide so far, then in theory your videos should never Transcode. If they are anyway, here are all the triggers I've discovered, and what I do to work around them:
.mkv
or .mp4
instead..srt
subtitles..srt
language specification (say, .ja.srt
) is for a non-ASCII language. Plex detects this and burns them in automatically.If you're desperate to stop Plex from transcoding video, you can tell it not to under Settings -> Transcoder
:
Be warned, however, that while playing remotely you might get this funny message:
Roku TVs don't support anything but Latin characters, and there is no way to install extra fonts yourself. However, if you have a Chromecast, you can instead cast your media to it via the Plex-Chromecast integration, and the UTF8 will display correctly. It will also display correctly in Plex Web.
Alternatively, you can choose to force Plex to burn-in the subtitles. This will inject the UTF8 characters on Plex's end, but will cause Transcoding.
You just need to fresh the metadata for that Library entry: