selfhost.directory

The index of self-hostable projects — ranked, categorized and served with live updates.
Own your data and stop giving it to big tech.

GitHub
hls-restream-proxy logo

Self-host hls-restream-proxy

Lightweight HLS restream proxy for media servers

BetaOpen SourceMIT
Updated6 months ago
LanguagePython
Setup difficultyModerate
Stars
255
Port
8089 (HLS proxy HTTP listener)
Docker
ghcr.io/pcruz1905/hls-restream-proxy
Install with Docker

What is hls-restream-proxy?

hls-restream-proxy is a lightweight toolkit that sits between self-hosted media servers (Jellyfin, Emby, Plex via Threadfin/xTeVe) and upstream HLS/IPTV sources that require specific HTTP headers like User-Agent and Referer. It consists of a Python reverse proxy (hls-proxy.py) that adds headers and rewrites m3u8 playlists so segment requests also pass through it, a bash script (refresh-m3u.sh) that scrapes source pages to generate an M3U playlist with stable proxy URLs, and a detector tool (detect-headers.sh) to automatically discover which headers a stream needs. The proxy auto-learns Referer headers per upstream host and caches m3u8 URLs for an hour to handle token refresh transparently. It runs on Python 3.8+ with no pip dependencies, and can be deployed via Docker, Docker Compose, manual execution, or systemd user services. The project is MIT-licensed and aimed at homelab users running personal media servers.

Should you self-host hls-restream-proxy?

hls-restream-proxy scores 46/100 on selfhost.directory (how scoring works) and ranks #42 of 54 in Media Streaming. It has 255 GitHub stars.

There was no stable release in the past 12 months, so check the repository's recent activity before you rely on it.

Setup is moderate: expect some configuration beyond a single command. An official Docker image is available. It is MIT-licensed and written mostly in Python.

Its closest alternative on selfhost.directory is Invidious (81/100, 25 799 stars). It scores higher overall, so compare the two before you pick. See hls-restream-proxy vs Invidious side by side.

Features

  • Auto Referer learning
  • Auto token refresh
  • Bandwidth declaration
  • Header detection tool
  • HLS header injection
  • IP allowlist
  • M3U Playlist Generation
  • Multiple extraction modes
  • Playlist Rewriting
  • Upstream M3U ingestion

hls-restream-proxy README

How to install hls-restream-proxy

Install hls-restream-proxy with Docker

Environment variables
HLS_PROXY_PORT, HLS_PROXY_BIND, HLS_PROXY_UA, HLS_PROXY_REFERER, HLS_ALLOWED_IPS, HLS_CACHE_TTL, CHANNELS_CONF, HLS_DEFAULT_BANDWIDTH, M3U_OUTPUT, HLS_PROXY_URL, HLS_UPSTREAM_M3U_URL, HLS_UPSTREAM_M3U_REFERER, HLS_UPSTREAM_M3U_TTL

docker run -d --name hls-proxy
-p 8089:8089
-v ./channels.conf:/app/channels.conf:ro
ghcr.io/pcruz1905/hls-restream-proxy:latest

One-liner without cloning the repo

How to configure hls-restream-proxy

  • CHANNELS_CONF./channels.confPath to channel config file

    Path to channel config file

  • HLS_ALLOWED_IPSComma-separated client IP allowlist (empty = all)

    Comma-separated client IP allowlist (empty = all)

  • HLS_CACHE_TTL3600Seconds to cache scraped m3u8 URLs (per channel)

    Seconds to cache scraped m3u8 URLs (per channel)

  • HLS_DEFAULT_BANDWIDTHFallback BANDWIDTH (bits/sec) advertised in the master playlist when a channel has no value set in channels.conf

    Fallback BANDWIDTH (bits/sec) advertised in the master playlist when a channel has no value set in channels.conf

  • HLS_PROXY_BIND127.0.0.1Bind address (localhost only by default)

    Bind address (localhost only by default)

  • HLS_PROXY_PORT8089Proxy listen port

    Proxy listen port

  • HLS_PROXY_REFERERFallback Referer header (auto-learned from /channel/)

    Fallback Referer header (auto-learned from /channel/)

  • HLS_PROXY_UAMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36User-Agent sent to upstream

    User-Agent sent to upstream

  • HLS_PROXY_URLhttp://127.0.0.1:8089Proxy URL written into M3U

    Proxy URL written into M3U

  • HLS_UPSTREAM_M3U_REFERERReferer for upstream M3U fetch

    Referer for upstream M3U fetch

  • HLS_UPSTREAM_M3U_TTL3600Cache TTL for upstream M3U fetch

    Cache TTL for upstream M3U fetch

  • HLS_UPSTREAM_M3U_URLOptional upstream M3U playlist URL (e.g. Dispatcharr) to auto-register channels

    Optional upstream M3U playlist URL (e.g. Dispatcharr) to auto-register channels

  • M3U_OUTPUT/tmp/iptv.m3uOutput M3U file path

    Output M3U file path

FAQ

Can I use this with VLC or mpv?

Yes. The /channel/<slug> endpoint returns a standard HLS playlist. Any player that supports HLS can play it directly.

Does this work with Plex or Emby?

Not directly — Plex and Emby don't read M3U files. You need Threadfin or xTeVe between this proxy and Plex/Emby to make M3U sources appear as a local TV tuner.

Jellyfin thinks my stream is 20 Mbps when it's really ~6 Mbps?

This happens when the upstream returns a single-variant media playlist with no BANDWIDTH tag. Fix by declaring the real bitrate as the 9th pipe-delimited field in channels.conf, or set HLS_DEFAULT_BANDWIDTH globally.

Do I still need to transcode in Jellyfin?

The proxy itself never transcodes — it only fixes headers so Jellyfin can fetch the stream. Whether Jellyfin transcodes afterwards depends on the stream and the client. Most free HLS streams are H.264 + AAC, which direct-play on virtually every client.

Does this add latency?

No. The proxy is passthrough only — it forwards the exact same bytes from the upstream, no transcoding. The only added latency is the network hop through the proxy (typically <1ms on localhost).

Why not a Jellyfin plugin?

Standalone scripts work with any media server and any player. No .NET dependency, no breakage when Jellyfin updates, and it also works with VLC, mpv, or any HLS-capable player.

More in Proxy

Rate this project

Click to rate — no account needed.

0 comments

Posting as guest
Loading comments…