xTeVe

# xTeVe ## M3U Proxy for Plex DVR and Emby Live TV. Documentation for setup and configuration is [here](https://github.com/xteve-project/xTeVe-Documentation/blob/master/en/configuration.md). ## About this fork The upstream xTeVe project has been inactive since 2021. This fork is maintained privately for a single trusted LAN. It is Docker-only and built for amd64 only. There are no release archives and no self-update. What it adds over upstream: * Web UI redesign with a mobile and accessibility pass (responsive navigation, keyboard flow, focus visibility, ARIA announcements, contrast). * Plex API guide refresh: after a lineup or XEPG update xTeVe can ask Plex to reload the DVR guide. New settings: `use_plexAPI`, `plex.url`, `plex.token`. * Strict or relaxed handling of channels whose EPG source went missing in XEPG, with automatic re-mapping. * A wizard-completed flag so the setup wizard is not shown again on restart. * First-party Docker image with a static ffmpeg, runtime `PUID`/`PGID`, and a healthcheck. * Drone CI: vet, tests, web bundle check, Dockerfile lint, compose validation, image publishing. * Web UI embedded in the binary with `go:embed`. * Unauthenticated `GET /healthz` endpoint for container health checks. * The self-updater and the GitHub branch switching are removed. The plan for further work is in `tasks/improvement-plan.md`. ## Requirements ### Plex * Plex Media Server (1.11.1.4730 or newer) * Plex Client with DVR support * Plex Pass ### Emby * Emby Server (3.5.3.0 or newer) * Emby Client with Live-TV support * Emby Premiere --- ## Features #### Files * Merge external M3U files * Merge external XMLTV files * Automatic M3U and XMLTV update * M3U and XMLTV export #### Channel management * Filtering streams * Channel mapping * Channel order * Channel logos * Channel categories #### Streaming * Buffer with HLS / M3U8 support * Re-streaming * Number of tuners adjustable * Compatible with Plex / Emby EPG --- ## Running the container ### Image The image is built by Drone and pushed to a private registry: ``` registry.coadcorp.com/nathan/xteve ``` Tags: * `latest` and `` from the `master` branch. * `` and `` from every other branch. ```bash docker pull registry.coadcorp.com/nathan/xteve:latest ``` The image is linux/amd64 only. ### Start with Docker Compose Bridge mode (default). The web UI is on port 34400. ```bash docker compose up -d ``` Host networking. Use this if you want Plex or Emby to discover the tuner by SSDP/DLNA. Multicast does not cross the Docker bridge, so publishing UDP 1900 in bridge mode is not enough on its own. Linux only. ```bash docker compose -f docker-compose.host.yml up -d ``` In bridge mode you can still add the tuner manually in Plex or Emby with `http://:34400`. Both compose files pull `registry.coadcorp.com/nathan/xteve:latest`. To build locally instead, uncomment the `build:` block in the compose file, or run `docker build -t xteve:local .`. ### Environment variables | Variable | Default | Meaning | |---|---|---| | `XTEVE_CONFIG` | `/xteve/config` | Config directory inside the container. | | `XTEVE_PORT` | `34400` | HTTP port xTeVe listens on. | | `PUID` | `1000` | User id xTeVe runs as. Set it to the owner of the host config directory. | | `PGID` | `1000` | Group id xTeVe runs as. | | `TZ` | unset (UTC) | Time zone, for example `Australia/Sydney`. | The container starts as root, sets the `xteve` user to `PUID`/`PGID`, fixes the ownership of the config directory if needed, and then drops to that user before starting xTeVe. If the container is started with `--user`, the ids are left alone and xTeVe runs as the given user. The old `XTEVE_UID`/`XTEVE_GID` variables are still accepted as aliases. ### Volume The config lives in `/xteve/config` (declared as a volume in the image). The compose files bind it to `./docker-data/config`. It holds `settings.json`, the mapping and EPG data, backups and the cache, so it is small enough to back up as a whole. If an older container kept its config in `/config` or `/home/xteve/.xteve`, the entrypoint copies it to the new location on first start. ### Healthcheck The image has a `HEALTHCHECK` that requests `http://127.0.0.1:${XTEVE_PORT}/healthz` every 30 seconds. The endpoint needs no authentication and returns the version and whether a scan is in progress. `docker ps` shows the state as `healthy` or `unhealthy`. ### ffmpeg A static ffmpeg and ffprobe are in the image at `/usr/local/bin/ffmpeg` and `/usr/local/bin/ffprobe`, taken from the pinned `mwader/static-ffmpeg` image. In a container xTeVe defaults `ffmpeg.path` to that location. VLC is not included. --- ## Security notes * This fork is meant for a trusted LAN. Do not put it on the internet. * Web authentication is off by default. Turn it on under Settings > Authentication before you expose it any further than the LAN, for example through a reverse proxy. * `/healthz` is always unauthenticated. It reveals the version and scan state only. * The container starts as root to apply `PUID`/`PGID` and then drops privileges. Start it with `--user` if you prefer it never to run as root. --- ## Development See [README-DEV.md](README-DEV.md) for the layout, how to build the binary and the web UI, and how CI publishes the image.