While I’ve described some of the pieces in my media setup, I have not described it as a whole. I started the process when I got annoyed with DVDs that don’t allow you to skip the copyright warnings, commentary disclaimers, trailers, endless menus, studio logos, and other crap when I simply wanted to watch the movie. It was time for something better, and now I have it.
I’ve written some on my storage setup before, but I’ll describe it briefly here. I bought an Antec 300 case, Intel server-class motherboard, 6 WD 2TB Black drives (before the flood that drove up the prices), and 4G of RAM (later upgraded to 12GB). The machine is booting Ubuntu 11.10 (not yet upgraded to 12.04) off a pair of USB flash drives which are configured in a software mirror. The 6 drives are configured in a raidz2 configuration (raid6 redundancy) yielding 8TB of disk space (or 7.2TB if you count in base 2 instead of 10). The raid contains all the media is an a sub-filesystem so it can be snapshotted/backed up independently (taking advantage of ZFS’s capabilities here).
All the storage in the world isn’t useful if there isn’t anything to put on it. I’ve experimented with several different forms, but I’ve finally settled on ripping my DVDs and BluRays to MKV files. I added a SATA card and a BluRay burner to my storage array for this purpose. Most would rip DVDs using Handbrake, but since I have the space, I’m doing a lossless conversion. I’ve been using MakeMKV to rip the DVD content into an MKV file which contains the original MPEG-2 video, AC3 audio, and DTS audio (when present). I only include the subtitles when I need them. When it comes to ripping BluRays, there’s little choice beyond using MakeMKV for the actual rip process. The resulting file can be run through Handbrake to transcode, but I’m still experimenting with keeping the original file. In that case, it contains the original H.264 video and DTS-HD or Dolby TrueHD audio.
In my case, the server and the storage are the same hardware, but there’s also the software component as well. In the past I worked on a plugin for Frontrow (on the Mac) and the AppleTV. It did a nice job of cataloging my movies and TV shows. I’ve never been happy with any of the other solutions, so I ported this over. In doing so, I realized that I should change it from client-only to a client-server relationship, but a client-server relationship brings it own set of challenges. For instance, it makes little sense to design a server that’s only capable of supporting a single client, so the server has to be designed with concurrency in mind. At first I thought of playing with a C based metadata server, but quickly I realized that I would be far better off using a Java based server due to its superior threading models and concurrency primitives.
I decided to transfer everything over HTTP where the client will make its requests via HTTP GETs and information from the server is transferred via JSON. I also decided that I’d put a majority of the intelligence in the server, so the client only makes requests of URLs which the server provided in a previous response. The initial connection is advertised via mDNS and extra information can be transferred via HTTP headers. So, when the client starts up, it listens for mDNS broadcasts of the server and makes the initial connection. The server tells the client to present the user with a list of items, where each item contains a title, preview information, the URL to access when the user selects the item, and what type of display is contained at that URL. Additionally, there are URLs for the list menu and the contextual menu of each item. So, with a small set of display primitives, I have a fully functional set-top display all delivered by a server. Furthermore, due to having a client-server system, when I get more set-top boxes, the information is automatically synchronized between them. So I can stop playback in one room, and resume it in another.
I spent a while trying to find a good client. I originally looked into a Roku, but I found it terribly lacking. Furthermore bringing up any such deficiencies in the forums brought on the wrath of its fanboys. The final straw was trying to deal with Roku’s terrible programming language, brightscript, and making it actually do something useful (for more info see my post on their forums). The Roku is now a black piece of plastic sitting in a closet, where it belongs.
I later bought a GoogleTV, particularly the Sony NSZ-GT1. It seems to have gone up to nearly $300 which is significantly more than the $170 I paid for mine in Nov. I selected this device because it not only can play high bitrate 1080p content, which the Roku claims but fails to deliver, but it can also play nearly any other content that I have such as AVIs, MKVs, MP4s, FLVs, and even MPEG2. Furthermore, it’ll play the typical codecs found in these files, including passing through the AC3 or DTS to a decoder. In short, it plays nearly everything that I’ve thrown at it, so it makes an excellent set-top box for playback. Soon, more manufactures are supposed to be releasing their GoogleTVs which should drive the price back down.
Since the programming language used on the GoogleTV is Java, I was able to significantly reduce my time spent parsing data from the server. I created a set of Java objects which defined the data I wished to transfer, and simply copied these objects to the client. Then I simply used the Jackson library to serialize and deserialize these objects to and from JSON on both ends. Additionally, the client is powerful enough to do some interesting additions. The GoogleTV is currently lacking the ability to display subtitles, so I added it myself. I currently can display both SRT and VobSub (IDX/SUB) subtitles. I suppose I’ll be adding SUP in the future to support BluRay subtitles, but since its format is similar to VobSub, I expect it to be a simple process.
So, there it is. I have a set-top box from which I can play anything that I own. Whenever I get a new disk, I immediately stick it in the server and rip it without ever playing it in an actual player. I remember seeing a commercial as a kid depicting the future. It had some kids in a household scrolling through a list of movies on the TV, selecting one, and it immediately played. Back then, the idea was not feasible, but now I have it.