An HLS proxy that intercepts live streams and burns WebVTT subtitles directly into the video.
2.7K
An HLS proxy that intercepts live streams and burns WebVTT subtitles directly into the video, producing a single-track output compatible with any player — including those that don't support HLS subtitle tracks (Roku, many smart TVs, etc.).
If you are viewing this on Docker Hub you can find the source repository on Gitlab at nodeto/hls-subtitle-proxy or by clicking here.
docker run -d \
--restart unless-stopped \
--name hls-subtitle-proxy \
-p 8081:8080 \
-e UPSTREAM=http://your-iptv-source/playlist.m3u \
kjoyce77/hls-subtitle-proxy
Point your IPTV client at http://<host>:8081/playlist.m3u.
.ts segment + matching subtitle cues, then uses ffmpeg to burn the subtitles into the video in real time.All settings are configured via environment variables.
| Env Var | Default | Description |
|---|---|---|
UPSTREAM | Upstream M3U playlist URL (required) | |
EXT_URL | (derived from listen address) | External URL clients use to reach this proxy |
CHANNELS | Comma-separated list of channel IDs | |
CONFIG | Path to a channels.json config file (mount into container) | |
PRESET | medium | x264 speed preset (ultrafast … veryslow) |
WORKERS | 2 | Number of concurrent ffmpeg encode workers |
CACHE_DIR | (auto temp dir) | Directory for cached encoded segments |
VERBOSE | Set to any value to enable verbose logging | |
ADDR | :8080 | Listen address (host:port) — note: this only affects the listen address inside the container; change the host-side port via Docker's -p flag instead |
Channels can be configured in two ways:
CHANNELS env — comma-separated list of channel IDs:
-e CHANNELS=csi,law-and-order,star-trek-1
Mounted config file — mount a JSON file into the container and set CONFIG:
-v /path/to/channels.json:/app/channels.json:ro
A channels.json file looks like:
{
"channels": [
"csi",
"law-and-order",
"star-trek-1"
]
}
If a channels.json is mounted to /app/channels.json it will be picked up automatically without needing to set CONFIG.
Minimal — proxy all channels:
docker run -d \
--restart unless-stopped \
--name hls-subtitle-proxy \
-p 8080:8080 \
-e UPSTREAM=https://example.com/playlist.m3u \
kjoyce77/hls-subtitle-proxy
With channel filtering and encoding preset:
docker run -d \
--restart unless-stopped \
--name hls-subtitle-proxy \
-p 8080:8080 \
-e UPSTREAM=https://example.com/playlist.m3u \
-e CHANNELS=csi,star-trek-1,doctor-who-classic \
-e PRESET=fast \
-e EXT_URL=http://myserver.local:8080 \
kjoyce77/hls-subtitle-proxy
With a mounted config file:
docker run -d \
--restart unless-stopped \
--name hls-subtitle-proxy \
-p 8080:8080 \
-e UPSTREAM=https://example.com/playlist.m3u \
-v /path/to/channels.json:/app/channels.json:ro \
kjoyce77/hls-subtitle-proxy
Docker Compose:
services:
hls-proxy:
image: kjoyce77/hls-subtitle-proxy
ports:
- "8080:8080"
environment:
UPSTREAM: https://example.com/playlist.m3u
CHANNELS: csi,law-and-order,star-trek-1
PRESET: fast
restart: unless-stopped
MIT License - see LICENSE for details.
Content type
Image
Digest
sha256:cef03db50…
Size
59.9 MB
Last updated
6 months ago
docker pull kjoyce77/hls-subtitle-proxy