01 January 2021

Last weekend was the perfect time to hack something that bugs me for a while. At home, one of my RaspberryPI is serving all my media via an Apache server. It’s simple and reliable. The main use is to stream content to the Chromecast. The workflow isn’t amazing but suits me:

So far it’s ok, but it gets tricky when it comes to stream an .mkv file because this format isn’t natively supported by Google Chrome. Opening it will start the download instead of showing the video player. In this case, the workflow is to:

After writing it down, it doesn’t sound like a big hassle, but damn it’s annoying. Especially if you plan to watch a ton of short videos.

The solution in mind: hack the template engine of Apache that generates the HTML indexes to inject the Cast script.

Screenshot of an Apache index

Apache indexes: look at this beauty

Sounds fairly simple and easy, but after some research it isn’t. The only customisation that Apache allows is adding a style file. Back to square one.

What about a single page app! Let’s imagine, place a HTML file somewhere on your Apache folder. By being served from the same domain, it can make requests to other folders and parse the index.html then recreate the directory navigation. It sounds ideal: a simple html file which does all the magic, and can be placed on any server without touching the Apache config.

Along the way, everything seemed fine. The parsing was simple to do, the style was under my control and the list of files was filtered to show video files only.

Then comes the Chromecast integration. Back in the days (2015, the early days of the Chromecast) my pet projects consisted of adding the Chromecast functionality to my favourite french TV channels, by a simple script injection. So it felt like the Cast part would be a piece of cake. Well…

In the meantime the Cast API has changed. It’s still retro compatible but the place is no longer familiar to my memories. My anger reached the sky when the basic tutorial from the docs wasn’t working on my environment. Alas, my old code from back in the days wasn’t working either. It was clunky, sometimes it was working, sometimes it did not. It’s only after reading the docs again that my attention stopped on:

Warning: Chrome sender apps need to support HTTPS to maintain Cast compatibility, as Chrome is deprecating support for the Presentation API on insecure origins.

Obviously my Apache server isn’t running on HTTPS. My first thought was to abandon here, sadly I’m stubborn as f***. Here are the other directions I tried to run into:

Workflow of the ApacheCast. From the directory browsing generated by page scrapping to the redirection to the cast page to stream videos.

If you want to stream a URL to a Chromecast without hassle: fire a new tab to https://maxwellito.github.io/apachecast/cast.html#[URL_TO_CAST]. There’s just one big button. Once the receiver is selected, the stream starts.

The Apachecast source code is available on GitHub.

So what lessons to get from this:

  1. Remember that Chrome considers localhost differently than other domains while on HTTP. It lets you use HTTPS reserved features (like Cast API and PWA) even if it doesn’t meet the security requirements. Which might make you feel that everything works, until you test in real conditions.

  2. The API could be more helpful and provide the real reasons why things don’t work, and not just No cast extension found (especially since no extension is longer required). There are so many failing reasons but without information it felt like debugging a web page on IE6.

  3. Next time I will install Plex and shut the fuck up.