Skip to content

Repository files navigation

StreamGate — IPTV Streaming Gateway

A small, boring and reliable HLS-aware IPTV streaming gateway written in Go.

Proxy, rewrite and reliably deliver IPTV streams without running a full IPTV management stack.

CI Release Container Go version License

StreamGate is deliberately not an IPTV management suite. It does not manage a media library, replace Jellyfin, or try to become another IPTV panel. It focuses on the streaming data plane.

Why StreamGate?

Many IPTV proxies are either thin URL-forwarding layers or complete media-management platforms. StreamGate sits between those two extremes: it keeps the deployment small while treating stream delivery as infrastructure.

  • HLS-aware, not extension-aware. Playlists are parsed as a graph of variants, renditions and media resources instead of checking whether a URL ends in .ts.
  • Reliability without a control-plane stack. Sources can fail over, concurrent segment fetches are deduplicated and continuous streams can be shared.
  • Provider URLs stay private. Clients receive opaque resource IDs rather than user-controlled ?url= proxy endpoints.
  • Correctness is testable. HLS rewriting, provider parsing, failover, caching and streaming behavior are exercised with unit, golden and end-to-end tests.
  • Operationally boring. One static binary, strict YAML, structured logs, Prometheus metrics, graceful shutdown and a hardened container image.

StreamGate currently accepts M3U and Xtream live-TV providers and serves gateway M3U, HTTP/HLS streams, read-only catalog APIs and an optional Xtream-compatible live-TV subset. Transcoding, WebUI, EPG management, DVR, VOD and series management are intentionally out of scope.

Quick start

Choose one of the two supported installation methods.

Option 1: Docker image

The published image supports Linux amd64 and arm64. Docker is the only runtime requirement.

mkdir streamgate && cd streamgate
curl -fsSL https://raw.githubusercontent.com/MrSibe/streamgate/v1.0.0/configs/example.yaml -o config.yaml

Edit the provider URL in config.yaml, then run the latest published package:

docker pull ghcr.io/mrsibe/streamgate:latest

docker run -d \
  --name streamgate \
  --restart unless-stopped \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --cap-drop ALL \
  --security-opt no-new-privileges:true \
  -p 8080:8080 \
  --mount type=bind,source="$(pwd)/config.yaml",target=/app/configs/config.yaml,readonly \
  --mount type=volume,source=streamgate-data,target=/app/data \
  ghcr.io/mrsibe/streamgate:latest

Use ghcr.io/mrsibe/streamgate:1.0.0 instead when you want to pin this exact release. Docker Compose, NAS and reverse-proxy examples are covered by NAS deployment.

Option 2: Release binary

Download the archive for your operating system and architecture from the latest GitHub Release:

  • Linux: linux_amd64.tar.gz or linux_arm64.tar.gz
  • Windows: windows_amd64.zip or windows_arm64.zip
  • macOS: darwin_amd64.tar.gz or darwin_arm64.tar.gz

Each archive contains the binary, example configuration, documentation and license. Verify it with the published checksums.txt, extract it, then edit configs/example.yaml and start StreamGate:

cp configs/example.yaml config.yaml
# Edit config.yaml, then run:
./streamgate -config config.yaml

On Windows, use Copy-Item configs/example.yaml config.yaml, edit the copy, then run .\streamgate.exe -config config.yaml in PowerShell.

Open these endpoints:

Playlist:  http://localhost:8080/playlist.m3u
Health:    http://localhost:8080/healthz
Metrics:   http://localhost:8080/metrics
Channels:  http://localhost:8080/api/v1/channels

Load playlist.m3u in VLC, Jellyfin, Emby, Plex or another IPTV client.

How it works

flowchart LR
    P[M3U / Xtream providers] --> R[Channel registry]
    R --> S[Health-aware source selector]
    S --> T{Stream type}
    T -->|HLS| H[Parse and rewrite playlist graph]
    H --> O[Opaque resources]
    O --> C[Segment cache and singleflight]
    T -->|Continuous HTTP / MPEG-TS| F[Bounded fan-out session]
    C --> U[Provider]
    F --> U
    H --> X[Client]
    C --> X
    F --> X
Loading

For HLS, StreamGate discovers every known URI, resolves it against the current playlist, stores the upstream mapping server-side and returns a short-lived gateway resource URL. Clients never need the original provider URL. HLS clients share segment work through the cache; continuous streams use a separate bounded fan-out model.

Read the detailed architecture and HLS proxy design.

HLS compatibility

HLS behavior Support
Master and media playlists ✅
Relative and absolute URI resolution ✅
Variant streams and I-frame playlists ✅
Alternative audio and subtitle renditions ✅
EXT-X-KEY and EXT-X-SESSION-KEY ✅
EXT-X-MAP and fMP4 media ✅
EXT-X-BYTERANGE preservation ✅
Query parameters ✅
LL-HLS parts, preload hints and rendition reports ✅
Content steering and image playlists ✅

The rewriting pipeline is covered by focused tests and golden playlist fixtures. Unknown tags, comments and ordering are preserved, but unknown vendor URI attributes are not guessed or rewritten. Non-HTTP key-system and inline data URIs remain untouched.

Streaming features

Reliable delivery

  • Atomic provider refresh with last-known-good snapshots
  • Deterministic multi-provider channel merging by stable tvg-id
  • Passive health tracking and bounded active recovery checks
  • Health-then-priority source selection and pre-commit failover
  • Range and conditional request forwarding

Efficient sharing

  • Bounded in-memory LRU and optional persistent disk cache
  • singleflight deduplication for concurrent segment misses
  • Separate handling for live playlists and cacheable media resources
  • One upstream continuous-stream session for matching subscribers
  • Bounded subscriber queues that disconnect slow clients without blocking others

Secure by default

  • Random 128-bit opaque HLS resource IDs
  • SSRF checks during DNS resolution, dialing and every redirect
  • Private-network providers require explicit opt-in and hostname allowlisting
  • Client cookies and authorization headers are not forwarded implicitly
  • URLs, query tokens and credentials are excluded from logs and health output

Observable

  • Structured JSON logs and request IDs
  • Prometheus metrics under the iptv_ prefix
  • Cache, session, source-health and failover statistics in /healthz
  • Optional pprof on a separate, disabled-by-default admin listener
  • A standard-library concurrent load generator in cmd/loadgen

Choosing the right project

StreamGate is inspired by the IPTV proxy ecosystem, but it deliberately optimizes for a narrow streaming data plane rather than the largest feature set.

Project Best suited for
StreamGate A lightweight, HLS-focused streaming gateway with explicit correctness and observability
KPTV Proxy A full-featured IPTV platform with management features
Threadfin Plex, Jellyfin and Emby-oriented M3U/DVR integration
iptv-proxy A straightforward M3U and Xtream reverse proxy
StreamShare IPTV account sharing and multiplexing workflows

If you need a WebUI, EPG management, DVR workflows or a broad Xtream ecosystem today, a larger platform may be a better fit. Choose StreamGate when the streaming path itself is the part you want to keep small, inspectable and dependable.

Configuration and API

StreamGate v1 uses strict YAML with config_version: 1. Unknown fields and missing ${ENV_NAME} references fail at startup. Start from configs/example.yaml, then use these contracts for production deployments:

Private, loopback and local upstreams are denied by default. See the configuration contract before enabling a LAN provider.

Benchmarks

Microbenchmarks cover HLS rewriting, M3U parsing and parallel memory-cache hits. The load generator measures a running gateway with controlled concurrency and reports throughput, failures, bytes and P50/P95/P99 latency.

make bench

go run ./cmd/loadgen \
  -url http://localhost:8080/resource/RESOURCE_ID \
  -requests 1000 \
  -concurrency 20

Benchmark numbers are environment-specific. The benchmark methodology documents how to collect reproducible results without turning a development-machine snapshot into a production claim.

Development and contributing

The most useful contribution is a real compatibility case. If an M3U, HLS stream or player fails, open an issue with a minimal sanitized playlist, expected behavior and relevant logs. Never include provider credentials or reusable stream tokens.

Before submitting a change:

go test ./...
go test -race ./...
go vet ./...

A provider-specific regression should become a minimal fixture and a test whenever possible. Over time, that compatibility corpus is more valuable than another unchecked feature box.

See the roadmap for released milestones and current non-goals.

License

Apache-2.0

About

A lightweight, reliable IPTV streaming gateway written in Go.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages