This page permanently redirects to gemini://shit.cx/tech/uncategorised/2020-12-16-a-self-hosted-netflix-clone/.

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:///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 = 
BACKBLAZE_APPLICATION_KEY = 
export BACKBLAZE_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.

Proxy Information
Original URL
gemini://shit.cx/tech/uncategorised/2020-12-16-a-self-hosted-netflix-clone
Status Code
Success (20)
Meta
text/gemini;
Capsule Response Time
2942.449795 milliseconds
Gemini-to-HTML Time
1.925172 milliseconds

This content has been proxied by September (3851b).