Files
projects/Dockers/self-hosted-iptv/README.md
T
Bram 5218d624d7
Build and Push Docker Images / build-and-push (push) Successful in 22s
select dutch audio
2026-02-11 21:59:05 +01:00

64 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 entries. Each entry can be:
- **String:** `"movies"` or `"series/Show Name"` — path to videos; EPG title and TMDB search use the folder name.
- **Object:** `{"path": "series/W817", "display_name": "Phineas en Ferb", "tmdb_search": "Phineas and Ferb"}``path` is required; `display_name` is shown in the EPG; `tmdb_search` is used when querying TMDB. You can use `tmdb_id` instead of (or to override) `tmdb_search` for a direct lookup, e.g. `97596` or `"97596-kika-bob"` (the numeric ID is extracted).
2. Run the container with volumes:
```bash
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 \
self-hosted-iptv
```
When using TMDB metadata, mount `/data` read-write (as above) so the app can store and reuse metadata in `/data/tmdb_cache/`. Use `-v /path/to/data:/data:ro` only if you do not use TMDB.
**EPG timespan:** Set `EPG_TIMESPAN` to control how far ahead the guide is generated (default `14d`). Examples: `2d`, `7d`, `48h`. The randomized schedule is refreshed after (timespan 3 hours) so a new block of content is ready before the current one ends. Example: `-e EPG_TIMESPAN=2d` gives 2 days of EPG and a new schedule every 45 hours.
**Optional EPG metadata (Dutch) from TMDB:**
To show series titles, episode names, and descriptions in the TV guide in **Dutch**, set a [TMDB API key](https://www.themoviedb.org/settings/api) (free after sign-up):
- `TMDB_API_KEY` your TMDB API key (v3).
Series are matched by folder name (e.g. `series/W817` → search "W817"); episode info is matched from filenames like `S01E01`. All metadata is requested in Dutch (`language=nl`).
- **Persistent cache:** Fetched metadata is stored under `/data/tmdb_cache/` (series search, series details, episode, episode credits). When generating the EPG, the app checks this cache first and only calls TMDB for missing entries. Mount `/data` read-write (omit `:ro`) so the cache can be written.
- **Rate limit:** TMDB allows 40 requests per 10 seconds. The app enforces this limit when calling the API; if the cache is warm, few or no requests are made during EPG generation.
**Logging:** Set `LOG_LEVEL=DEBUG` (e.g. in your `docker run` with `-e LOG_LEVEL=DEBUG`) to see where time is spent: schedule building (including ffprobe per video), EPG per-channel programme count and duration, and TMDB cache hits (memory/disk) vs API requests and rate-limit waits.
3. In your IPTV client or **Plex DVR**, add:
- **Playlist URL:** `http://<host>:8080/playlist.m3u`
- **EPG (XMLTV) URL:** `http://<host>:8080/epg.xml`
Plex will show programme titles and times for each channel.
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. The **schedule** (and EPG) is built from video durations (via ffprobe) so start/stop times match whats actually playing. The schedule is cached for (timespan 3 h) so the EPG and live stream stay in sync and a new span is ready in time.
## Endpoints
- `GET /` — simple web index with playlist and EPG links
- `GET /playlist.m3u` — master M3U for Plex DVR (one live stream URL per channel)
- `GET /epg.xml` or `GET /xmltv.xml` — XMLTV EPG (duration set by `EPG_TIMESPAN`, UTC)
- `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 (audio track is auto-selected: Dutch → Flemish → default)
## 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.