Save the shelves: how to stream a movie collection

c: | f: /

I have hundreds and hundreds of DVDs taking up space on shelves in my living room. A huge investment that I don’t want to lose, and I love movies. Time to get my geek on and find a better way. Step into my parlour to see how I did it…

There comes a time when enough is enough. The shelves in my living room are bowing under the weight of the hundreds of DVD cases they support. I love movies. I’ll happily delve into the collection, pick one and just lose myself in the escapism for a few hours. I don’t want to forego that just because I’m running out of physical space.

My multi-region, mod-chipped Sony DVD player is still going, despite being over twenty years old. But it’s starting to flake out occasionally, with bad disc reads, or some newer movies / scratched discs just refusing to play properly. Most are viewable through the PlayStation, but that won’t play back the Region 1 discs, which is annoying: the reason I chose those versions is because they usually have the coolest features, not available in this country.

So how do I preserve this collection, make it more accessible to me and the family, without sacrificing the immediacy of just picking a movie from the shelf and plonking myself on the sofa to be immersed in surround sound goodness?

Enter the Raspberry Pi as a low-cost and expandable media server. Say hello to my NAS

Huge DVD collection Raspberry Pi and WD Elements media server Raspberry Pi and WD Elements media server from side

(yeah, the elastic bands add something to the whole DIY nature, don’t they?)

Credit-card size tech to the rescue

I researched and figured a tentative solution based on best practice – separating storage and display, balancing speed, encoding, and so forth. But my tests weren’t quite working as flexibly as I wanted, so I bounced my ideas off a good friend who happens to have been down this road before. He outlined his approach and there were some great additions I’d not thought of.

I merged elements of his approach with mine so, in theory at least, I can take four shelves rammed with movies and condense them to tech the size of a couple of decks of playing cards.

The elements of this system are:

  1. A Raspberry Pi Model 3B.
  2. A Western Digital Elements 3TB USB drive.
  3. A Cluster Case to house the Pi, with tiny fan for additional cooling.

That’s it.

The system has the following components:

Stock Raspbian OS

The Pi runs this from its internal 16GB SD card, with a suitable hostname so I can identify it on the network. One user for now: the default ‘pi’ account.

Nginx web server

An almost-stock installation on the Pi, with a minor tweak to its config to add autoindex on to its location / section, making directories browseable.

Two network interfaces

Set up on consecutive static IPs – one wired, one wireless – via /etc/dhcpcd.conf. This is so that IP address resolution is atomic to the device and not reliant on the router, which may change from time to time by my internet provider.

interface eth0
static ip_address=aaa.bbb.ccc.ddd/24
static routers=aaa.bbb.ccc.ggg
static domain_name_servers=aaa.bbb.ccc.ggg

interface wlan0
static ip_address=aaa.bbb.ccc.eee/24
static routers=aaa.bbb.ccc.ggg
static domain_name_servers=aaa.bbb.ccc.ggg

Using both networks allows access over either, which is no bad thing in case we suffer congestion on one. Even though this model Pi is limited to 100mbps wired, I have a gigabit switch to handle wired traffic, and three wireless access points available, so my next Pi can take advantage of the greater bandwidth.

The USB drive

Formatted as ext4, this is powered via the Pi’s USB port. It automounts on boot via /etc/fstab and has two subdirectories in its single partition:


These are owned by the local user with 775 permissions. Each ripped movie will be in its own subdirectory, so that I can rip and collect together special features if I wish. Likewise, each TV series will be in its own subdirectory, with a further subdirectory for the season number, then each ripped episode comprises the full name-season-episode-title as its filename. This makes it easier for media players such as Kodi to figure out which episodes belong to a collection, and in which order to play them.

These two main directories are symlinked from the Nginx default web server docroot so they can be browsed from any networked device in the house.


A stock installation on the Pi, with the USB drive’s mount point exposed to Windows machines in its ‘/etc/samba/smb.conf’ as follows:

Comment = Streaming server
Path = /mnt/share-name
Inherit permissions = yes
Browseable = yes
Writeable = yes
Public = yes
Create mask = 0644
Directory mask = 0775
Force user = pi

Using the above settings means that Windows can write directly to the USB drive over the network (more on this in a moment). Forcing the user to be ‘pi’ is a little annoying, but it avoids permission/authentication issues from the PC, as it doesn’t have a ‘pi’ user.

Ripping movies

After much experimentation, I’ve configured a custom preset in the encoding app Handbrake to rip movie content off my main PC’s DVD drive. I chose the following features and settings:

  • Matroska’s .mkv container format because it can handle multiple audio streams and subtitle tracks easily.
  • H.264/x264 encoded mp4 with a constant bit rate, the same frame rate as the original disc, and a quality of 19 using the ‘film’ tune setting. Interlacing decomb is performed too, just in case.
  • Dolby Digital or DTS audio streams are passed through untouched to the final ripped .mkv file, because I don’t want to compromise on sound. I label each track appropriately so I know which is which.
  • Two-channel secondary stereo tracks for special features or audio commentaries are compressed using AAC to Dolby Surround or Stereo at a suitable bit rate just below that of the original.
  • All subtitles are ripped as-is.
  • The libdvdcss decrypter has been added to Handbrake so it can decode the movie’s copy protection as part of the ripping process.

When I hit the Go button, it chunters away on the PC for an hour or two and transcodes the movie, writing it directly across the network (via the Samba share) to the USB drive on the Raspberry Pi. This saves writing it locally and then performing a lengthy copy operation afterwards.

A typical 2- or 2.5-hour movie will compress down to between 1.5 to 3.5GB this way. Way smaller than the original VOB/MPEG-2 stream (usually between 4 and 9GB), resulting in fewer bytes transferred over the network for smoother playback.

Streaming over the network

Now the media server is sitting there, the Raspberry Pi in its sexy case atop the drive, barely a whisper from the fan, I can do one of the following:

Fire up the laptop

It has Kodi on it, so I simply add the /movies and /tv network shares (via Nginx) and inform it one contains Movies and one contains TV shows. By telling it to scan the shares on startup, it automatically indexes any new content that has been ripped.

With the laptop plugged into my surround sound amp via Thunderbolt/HDMI, I can lounge on the sofa with my phone running the Kore app to act as a remote control for Kodi. Thus I can browse the collection, play a movie and enjoy it in glorious surround sound.

Grab a tablet or phone

Installing the VLC media player onto any device allows me to browse the network share, choose Movie or TV, and scroll through the available items to play back the content.

Future: add another Pi as a media server

I could buy another Pi and install the default Raspbian operating system, then add Kodi to it. By sticking that near the TV connected to the amp over HDMI, our movie collection would be available on-tap in the living room, instead of having to fetch the laptop each time.

Future: stream other stuff

I might rip and encode my CD library in the same way. Kodi is equally happy streaming audio, so that’s potentially another piece of furniture we can repurpose or sell on.

Expansion options

Crucially, separating the storage and playback as described above leaves the Raspberry Pi some headroom. It’s possible to run Kodi on the same Pi as the one serving files, but that might result in choppy playback as it tries to access the disk controller and decode the stream at the same time.

If I run out of space on the 3TB disk, I can buy another disk and either:

  1. Attach it to the existing Pi via another of its USB ports – if the power draw isn’t too great (or buy a powered drive next time).
  2. Buy a second Pi and configure it as above: one Pi per disk. The Cluster Case already comes with a second layer and another fan, so I can add the new Pi atop the existing one and stash both disks under the stack. If I need further storage, I can buy a second cluster case and either stack it on or alongside the existing pair, or house it in another room.

One issue is that each Pi will require a power supply via an adapter and a corresponding three-pin socket in the house. But there are 6- or 10-port USB “charging” hubs available that are designed to charge phones and tablets. One of these can operate off a single three-pin socket and provide 60W shared across the USB ports, which is plenty.

Using a tiny USB-to-micro-USB cable per Pi, the charging hub can power the lot; much neater than having a bunch of ugly wall plugs everywhere.

Backups and fault tolerance

But what of Stef’s data survivity law I hear you cry? Surely all movies in one virtual basket is a disaster waiting to happen? Well, yes, I haven’t thought that far ahead yet. I will probably box up the original DVDs in the loft (or keep the inlays and discs and throw the plastic casings of the non-special editions) so if the drive ever fails I can at least rip them again (providing I still have a DVD drive in my PC).

Better, would be some kind of second disk – perhaps in my main PC – that is periodically synced with the media server drive(s). In theory, I could employ RAID-1 on the Pi to mirror the content onto two physical drives but I’ve had a bad experience with RAID-1 where corrupt data on the first was mirrored to the second, trashing both copies. RAID-5 (striped, with parity) is an option, but expensive when dealing with multi-terabyte drives.

Stashing backups onto Blu-Ray discs – even dual layer discs at 50GB a pop – would need a library of 60 discs to backup a single 3TB drive. That’s not only expensive but unwieldy and difficult to locate stuff I might need to restore in future if anything gets corrupted. On the plus side, it’s not magnetic data, so is impervious to mag pulses!

Going forward: users and security

There are still some kinks to iron out and things to improve or investigate.

It’d be nice to have each family member to have their own account, preferably without the drudgery of logging in each time. That way, I could create a dedicated directory on a media server for my boy’s movie collection. And over time, open up various other movies on the drive to his account, as and when he becomes mature enough to view them. Not sure how to handle any of that yet.

But on the whole, I’m pretty happy with the way this is shaping up. The PC is busy encoding discs in the background whenever it’s on, and the network library is (gradually) filling out. I expect it’ll be done next year :)

Love it when tech actually helps solve a problem instead of just being there for the sake of it.

4 cats scribbled here

    Shawn Holwegner

    I once felt this way -

    Back in the early 2000s, I started to encode everything to DivX. Remember that? Yeah.

    Then, MP4.

    Heck, back in 1997, I downloaded the entirety of

    .. and then my RAID crashed and I lost everything. EVERYTHING.

    Around 2006, I was forced to scan my then-new shuffle, full of mods I had converted into an MP3 at the Phoenix Airport. Yep, it got nuked, and I didn’t even bother to file a report.

    I have some DVDs that date back to 1997ish, and they’re still working better, and lasting longer than any non-physical media I’ve owned.

    For your next DVD player, I suggest a Philips; they’re easy to set region unencumbered, and automatically scale between PAL/NTSC. The DVP-642 was a favorite, but they’re old, and expensive. Nearly all of them are trivial to set to Region 0; and autoscale.

    Stef Dawson

    Thanks for the comment. Ah yes, I remember DivX with fondish memories. And I feel your pain with the RAID crash. It’s a horrible sinking feeling when you know the tech there to protect you fails so spectacularly.

    As it happens, the 3TB drive I bought from Amazon Marketplace turned out to be a refurbed unit and it started clicking like crazy on boot. So I backed up what I’d converted so far to my PC, then sent the drive back.

    Without the Marketplace discount, the sweet spot for price-per-GB-per-risk-of-loss was 2TB so I opted for one of those instead.

    I’m always cautious about all eggs in a single basket (cf. Stef’s Data Survivity Law) so I’m going to back up the ripped movies to any spare capacity I have on the JBOD in my PC. Worst case scenario then is a copy operation not a re-rip.

    Thanks also for the DVD player tip. I tended to have Sony stuff as I like the build quality, but when my STR-DB940 amp died I swapped it for a Pioneer VSX-933 which (just) pipped the equivalent Sony to the finish line in a features/price comparison. If the DVD player completely dies before I’ve finished the ripping process I might have to look at a replacement; I’ll consider the Philips.

    I’m definitely keeping the DVDs as some of them are collectors’ items or limited editions with graphic novels in them. Just not storing them on the shelves in the lounge, and I hope they’ll thank me.


    Looking for a similar answer to powering multiple Pis from one socket, I eventually found this: Bitscope Quattro.


    You will need to add fans and some risers to keep temperatures down. Without they run at about 50C – 60C. Still within their operating limits, but too warm for my liking.

    Available from CPC/Farnell in the UK.

    Stef Dawson

    @Nic. Oooh, interesting. Pricey, but some of that rackmount stuff looks seriously cool. Thanks for the tip!

Type away


(required, never made visible)

(optional, linked with rel="nofollow")