Files
projects/Dockers/self-hosted-iptv
Bram c4fcc55a39
Build and Push Docker Images / build-and-push (push) Successful in 2m7s
this would be awsome
2026-02-10 23:53:59 +01:00
..
2026-02-10 23:44:22 +01:00
2026-02-10 23:53:59 +01:00
2026-02-10 23:53:59 +01:00
2026-02-10 23:53:59 +01:00
2026-02-10 23:45:33 +01:00

Self-hosted IPTV

Serves M3U playlists that randomly schedule video files from /movies and /series, with the same show never appearing twice in a row.

Setup

  1. Create /data/channels.json (see data/channels.json.example).

channels.json format:

  • channels: array of channel objects
  • Each channel:
    • id: unique id (used in URLs)
    • name: display name
    • paths: list of path keys to include:
      • "movies" — all videos under /movies
      • "series/Show Name" — all videos under /series/Show Name
  1. Run the container with volumes:
docker build -t self-hosted-iptv .
docker run -d --name iptv -p 8080:8080 \
  -v /path/to/movies:/movies:ro \
  -v /path/to/series:/series:ro \
  -v /path/to/data:/data:ro \
  self-hosted-iptv
  1. In your IPTV client or Plex DVR, add playlist URL: http://<host>:8080/playlist.m3u

Each channel in the M3U points to a continuous live stream (/live/<id>): FFmpeg concatenates the channels randomized videos into one MPEG-TS stream and loops it, so Plex can tune and record like a normal TV channel.

Endpoints

  • GET / — simple web index with playlist link
  • GET /playlist.m3u — master M3U for Plex DVR (one live stream URL per channel)
  • GET /live/<channel_id> — continuous MPEG-TS stream for that channel (for tuning/recording)
  • GET /channel/<id>/playlist.m3u — single channel M3U (list of individual video URLs)
  • GET /stream?path=movies/... or path=series/... — stream a single video file

Shuffle behaviour

Videos are grouped by path (e.g. one group per show or the whole movies folder). Each group is shuffled, then items are interleaved round-robin so the same show never plays back-to-back.