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