Spooktober 2023
I hate writing because I’m terrible at it. As a result, I don’t write.
This post took me awhile to write because I hate writing.
haha welcome to my tumblr XD
Spooktober⌗
Every year for October Spooktober I like to set up a 24/7 livestream of horror movies for my friends. Last year I had a pretty jank setup using OBS and the VLC plugin to stream a playlist of movies to a selfhosted Owncast instance.
The results were mixed. OBS on a Windows VM without a dedicated GPU hogged a ton of CPU, stuttered, froze, etc. There was a huge amount of delay in the player, resulting in inconsistent timing for everyone watching.
This year I used a more advanced stack consisting of the following elements:
- ErsatzTV + Plex (I started off using Jellyfin, but there were some weird quirks I kept running in to with how media was handled)
- OvenPlayer
- nginx
- a shitty plugin that I wrote for Red Discord Bot so people could see the schedule via Discord. It’s not good, I will not share it.
Setting it up⌗
I already had an existing Plex setup, so getting the intial setup done was as easy as setting up a new VM and installing ErsatzTV. Connecting Ersatz to Plex was easy, and then I set up a simple collection of all movies tagged “horror”, and a few TV shows that also fit the bill (Tales from the Crypt fucking rules).
With ErsatzTV serving a channel, I had to figure out a way to make it public and not expose any of the rest of the Ersatz management console. I did this through nginx.
If you’re familiar with nginx, the below configuration should make sense. I’m proxying to the stream VM, and only allowing access to playlist files. I only have one channel, so the channel ID is 1.
upstream spooky {
zone spooky 64k;
server 192.168.254.254:5002;
keepalive 2;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' "";
}
server {
server_name my.stream.cool;
listen 443 ssl;
location / {
root /var/www/stream;
}
location /iptv {
deny all;
}
location /iptv/channel {
deny all;
}
location /iptv/session {
deny all;
}
location /iptv/* {
deny all;
}
location ~* ^/iptv/session/1/.+\.(ts|m3u8)$ {
deny all;
proxy_pass https://spooky;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 24h;
proxy_send_timeout 24h;
proxy_read_timeout 24h;
proxy_buffers 4 256k;
proxy_buffer_size 128k;
proxy_busy_buffers_size 256k;
}
location /iptv/channel/1.m3u8 {
proxy_pass https://spooky;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 24h;
proxy_send_timeout 24h;
proxy_read_timeout 24h;
proxy_buffers 4 256k;
proxy_buffer_size 128k;
proxy_busy_buffers_size 256k;
}
}
With the stream now available over the internet, I set up a web page with OvenPlayer and HLS, then invoked OvenPlayer like this:
const player = OvenPlayer.create("player_id", {
autoStart: true,
mute: true,
controls: true,
sources: [
{
type : "hls",
file: "https://my.stream.cool/iptv/channel/1.m3u8?mode=segmenter"
}
]
});
Boom, ErsatzTV on tap.
What I watched this year⌗
- Spookies
- Terror at Tenkiller
- Mandy
- The Blob
- Bone Tomahawk
- The Borrower
- The Brood
- Butcher, Baker, Nightmare Maker
- C.H.U.D.
- Chopping Mall
- The Conjuring
- Dead Space: Downfall
- Don’t Breathe
- The Empty Man
- Friday the 13th: Part 2
- Jason X
- Older Gods
- Pledge Night (i fucking hate this movie why did i watch it three times)
- Phantasm
- Return of the Living Dead
- A Cure for Wellness
- mother!
Comments
Markdown is supported in comments.
Your email is only required to notify you of replies. You are not required to enter your email.
An anonymized version of your IP is stored to generate a hash for your user avatar.
Author replies are highlighted with a purple glow.