Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
1–10 of 41 posts
Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#2Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#3Three problems: (1) the m3u8 URL is buried behind iframes and obfuscated JS, (2) tokens expire every few hours, and (3) the upstream server checks User-Agent and Referer headers on both the playlist and .ts segments — Jellyfin doesn't send these, so you get 403.
I ended up writing three scripts:
- detect-headers.sh: give it a page URL, it follows the iframe chain, extracts the m3u8, then brute-forces header combinations on both .m3u8 and .ts requests. Tells you exactly what the stream needs.
- hls-proxy.py: single-file Python reverse proxy (stdlib only, zero pip dependencies). Injects the required headers and rewrites the m3u8 so segment requests also go through the proxy.
- refresh-m3u.sh: extracts fresh URLs before tokens expire, outputs a Jellyfin-ready M3U with logos and channel groups. Runs on a systemd timer.
~200 lines of Python, ~100 lines of bash. The proxy is the interesting part technically — it has to handle relative and absolute segment URLs, rewrite URI= in EXT tags (for encryption keys), and add CORS headers since Jellyfin's web client makes cross-origin requests.
Happy to answer questions about the approach or implementation.
Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#4Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#5I self-host Jellyfin on my homelab and got frustrated opening a laptop every time there was a football match just to deal with popup-infested streaming sites. The actual video underneath is just a standard HLS stream, but getting it into Jellyfin turned out to be harder than expected. Three problems: (1) the m3u8 URL is buried behind iframes and obfuscated JS, (2) tokens expire every few hours, and (3) the upstream s…
How probable is it that this kind of method can be patched or obfuscated further? I assume that since the HLS stream is always at the core, it’s a matter of just finding alternative ways to dig through it.
Any quirks this implementation has wrt. things like quality or additional delay? Thanks! I’d like to try out if your methods could be used to make some sort of snippet that could be sent to VLC that’s running on a TV or streaming device.
Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#6Think it could be ran from within a docker container so I could add it to an existing docker compose media server setup?
Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#7I self-host Jellyfin on my homelab and got frustrated opening a laptop every time there was a football match just to deal with popup-infested streaming sites. The actual video underneath is just a standard HLS stream, but getting it into Jellyfin turned out to be harder than expected. Three problems: (1) the m3u8 URL is buried behind iframes and obfuscated JS, (2) tokens expire every few hours, and (3) the upstream s…
Either way, gonna make my World Cup viewing experience this year a lot easier haha
Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#8Very cool. I’ve used a paid service for years now that gets me all sorts of sports and channels very reliably, I would assume they’re doing something similar to make this work. Might try this though with my home server setup. Think it could be ran from within a docker container so I could add it to an existing docker compose media server setup?
Re: Show HN: I pipe free sports streams into Jellyfin – no ads, just HLS
#9Very cool. I’ve used a paid service for years now that gets me all sorts of sports and channels very reliably, I would assume they’re doing something similar to make this work. Might try this though with my home server setup. Think it could be ran from within a docker container so I could add it to an existing docker compose media server setup?
any chance you'd be willing to share what the service is? I use streameast all the time but it's not reliable enough