-- Leo's gemini proxy

-- Connecting to shit.cx:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini;

shit.cx


A Self-Hosted Netflix Clone


2020-12-16T20:19


I hate running fileservers at home. I move a lot (the joys of being a being a millennial and unaffordable housing) so I rarely have a place for a server; somewhere cool, with power and fast network, and accommodating for a noisy machine. A long time ago, I ran a server in my bedroom in an apartment without air-conditioning. That summer I had like three disk failures. I just don't bother anymore.


In 2015 I got NBN; Australia's nationalised broadband internet service. I had 100Mb fibre to my apartment. I decided that I would stream all my media from the cloud instead of shuffling HDDs around.


I've had a few different approaches now — I started on S3 and Lambda but that was expensive — but I've settled on something that I consider simple and cheap. The frontend is Kodi¹ running on a Raspberry Pi. The backend is Backblaze B2².


Kodi supports streaming from HTTP endpoints and Backblaze B2 can provide those HTTP endpoints. The trick is to plug them together. Kodi's strm files³ are they way I do this. Those files are static but the signed, temporary Backblaze urls aren't. The strm files instead point to an NGINX which serves a 302 redirect to Backblaze with valid tokens.


Let me show you how it works. Say we have a strm file named "the-running-man.strm" that contains this:


#EXTINF:6042,The Running Man
http://<host>/the-running-man.mp4

The first line is `EXTINF:<running time>,<title>`. This overrides the OSD so that it doesn't display the title as "the-running-man.strm", and instead shows a nice title. I can't remember why the running time was useful.


I have an NGINX config template that periodically updates the tokens in the redirect before they expire. The template looks a bit like this:


server {
  listen 80 default_server;
  server_name _;

  rewrite ^/(.*).mp4 ${API_URL}/file/${BACKBLAZE_BUCKET}/$1.mp4?Authorization=${ACCOUNT_AUTHORIZATION_TOKEN} last;
}

A Makefile builds the generated nginx config like this:


SHELL = /bin/bash -x
BACKBLAZE_ACCOUNT_ID = <mine>
BACKBLAZE_APPLICATION_KEY = <secret>
export BACKBLAZE_BUCKET = <my_bucket>

.DELETE_ON_ERROR:

etc/nginx.conf: export API_URL = $(shell jq -r .apiUrl etc/authorization.json)
etc/nginx.conf: export ACCOUNT_AUTHORIZATION_TOKEN = $(shell jq -r .authorizationToken etc/authorization.json)
etc/nginx.conf: etc/nginx.conf.template etc/authorization.json .FORCE
        envsubst < $< > $@

etc/authorization.json: .FORCE
        curl https://api.backblazeb2.com/b2api/v1/b2_authorize_account \
                -u "${BACKBLAZE_ACCOUNT_ID}:${BACKBLAZE_APPLICATION_KEY}" \
                2> /dev/null \
                > $@
        [[ -s $@ ]]

.FORCE:

And it's fired off from a cronjob:


17 * * * * make -C /redirector/path && /etc/init.d/nginx reload

This solution works well and is cheap. Assuming the movies have an average size of 1.5GB, storing a library of 2000 and watching 50 will cost $15.75 a month.


I don't know about the US Netflix, but the selection on the Australian one is pretty crap. Also, things are removed all the time. I like being in control of the content.


I don't know whether it's actually self-hosted since I'm using Backblaze? Perhaps not, but it's a long-way closer than Netflix.



¹ Kodi

² Backblaze B2

³ Kodi internet video and audio streams



---


More Posts Like This

Return to Homepage


The content for this site is CC-BY-SA-4.0.

-- Response ended

-- Page fetched on Thu Apr 25 01:59:04 2024