Around 18 months ago I set up a TVHeadend server using an Olimex Lime2 single board computer with the intention of having a single location for television recordings. I wanted something power efficient but fast enough to handle multiple simultaneous recordings and streams hence why I went for the Lime2 which has the option to connect a SATA hard drive instead of using USB like on the Raspberry Pi. The Lime2 also has gigabit ethernet which is beneficial but a fairly weak CPU compared to other single board computers so I had to be careful which software I used otherwise it wouldn’t handle the load.

After trying various applications I came to the conclusion that there wasn’t anything available that would do the required task. The following things were necessary:

  • It needed to be able to run on weak hardware (only a dual core with 1GB RAM).
  • It needed full Chromecast support as that’s our preferred method of watching television.
  • It needed a mobile friendly web interface for watching and creating recordings.
  • No subscription fees.

I tried a few different things and Plex seemed like the best option out of all of them, but the Lime2 wasn’t powerful enough and it seemed like a subscription fee would be needed to get all the features I wanted. I came to the conclusion that writing my own software would be the best option but it came with a lot of challenges.

TVHeadend by default records over the air transmissions as .ts files which isn’t natively supported by many systems; the Chromecast doesn’t support it at all. As the Lime2 simply isn’t powerful enough to do real-time video transcoding I wrote a Python script which reads the TVHeadend files (there’s no database – a new plain file is created for each recording to save its metadata) and then transcodes the .ts file to h264/aac .mp4 which all our devices support (Chromecast, native iOS, Android, Linux, Mac). The Lime2 transcodes at approximately 25% speed (eg, it takes 4 seconds to transcode 1 second of input) which is very slow so for that reason I also wrote a Python script for my laptop which would connect to the Lime2, grab the list of untranscoded files, complete one, and upload the final .mp4 back to the Lime2. I wanted to be able to run the script on multiple devices at once so lock files are created to prevent the same recording being transcoded by multiple devices – the Lime2 is configured to never transcode anything if there’s an external transcoder online as everything else can do it significantly faster; the Lime2 will only transcode as a fallback so I’m not forced to turn on a computer to make the recordings watchable. The only issue with this system is that recordings remain unwatchable for the length of the recording multiplied by 4 whenever my laptop is off/on battery/asleep which isn’t a big issue but it does mean that patience is required sometimes.

After that was complete, I was left with a directory full of .mp4 files so I needed to find a way to make them easy to browse and easy to stream to the Chromecasts. Once again, I used Python (and the pyChromecast library) to watch the recordings on any of our Chromecasts. I wrote a HTML/Javascript webapp to browse the recordings with Python CGI for the backend and it worked fairly well but anything involving the Chromecast was incredibly slow; pyChromecast is designed to remain connected at all times but as I was using it within Python CGI a new session was being created every time the webapp contacted the server. To fix the problem I wrote a server for pyChromecast which my CGI scripts can connect to, issue commands, and then disconnect from without affecting the Chromecast connection which fixed the slowness. You may be wondering why the Lime2 is the one doing Chromecast connections and not each client, here’s why:

  • The API I wrote is very simple – One day I could create/hack a hardware remote to provide more traditional television functionality to the system. This would be difficult if full Chromecast support was needed on each device.
  • The clients won’t get confused when they go to sleep and turn off their WiFi radios to save power like many Chromecast apps currently do.
  • The server can keep track of playback durations easier so that recordings can be resumed from their last position and/or marked as watched.

The whole system currently works but there’s quite a few bugs which I’m slowly fixing. When I first started working on this project it was only intended to be a few small scripts to provide better functionality to already existing applications so quite a lot of things are hard coded instead of being easily configurable; for that reason I’ve decided not to make this project open source just yet. Some major refactoring is required and then I’ll post the code so anybody can have their television recordings available for Chromecast streaming on the network.

Categories: Software

Leave a Reply

Your email address will not be published. Required fields are marked *