Sign inSign up

cplieger/plex-language-sync

By cplieger

Updated about 3 hours ago

Set preferred audio and subtitle languages per show; every new episode follows automatically

Image
Content management system
0

10K+

cplieger/plex-language-sync repository overview

plex-language-sync

Set your preferred audio and subtitle languages per show, and Plex applies them to every new episode automatically.

What it does

Plex lets you choose which audio track and subtitle language to use when watching a show, but that choice only applies to the episode you're currently watching. If you start a series in Japanese audio with English subtitles, you have to set that manually on every single episode, and again when new episodes arrive.

plex-language-sync eliminates that friction. It watches your Plex playback in real time and automatically propagates your audio and subtitle language choices to every other episode in the same show. Set your preference once on any episode, and the rest of the series follows, the way Netflix does natively.

It also learns your habits. If you always watch anime in Japanese with English subtitles, brand new shows that arrive (via Sonarr or manual import) get those settings applied before you even press play.

Key features:

  • Real-time WebSocket listener for play and library scan events
  • Per-show language propagation with scored stream matching (language, codec, channel layout, title, forced, hearing impaired, visual impaired, descriptive track filtering)
  • Language profiles: learns your audio→subtitle preferences from playback and applies them to brand new shows that have no watch history yet
  • Subtitle codec preference: when multiple subtitle tracks match the same language, prefers ASS over image-based (PGS) over plain text (SRT)
  • Configurable scope: entire show or current season only
  • Configurable range: all episodes or future episodes only
  • Ignore specific shows via Plex labels or entire libraries
  • Scheduled daily deep scan as a safety net: re-applies the per-show selections recorded from your playback, so a missed real-time event is repaired without guessing your choice from the server's current state
  • Persistent JSON cache survives container restarts
  • Multi-user support: fetches shared user tokens from plex.tv automatically; each user gets independent language preferences
  • Docker secrets support (PLEX_TOKEN_FILE)
Why this design
  • Single binary, small footprint. Written in Go; the only third-party runtime libraries are coder/websocket and golang.org/x/sync (the rest are the project's own support modules). No Python runtime, no YAML config files, no notification frameworks; just a distroless container that does one job well.
  • Rootless and minimal attack surface. Runs as nonroot (UID 65532) on gcr.io/distroless/static-debian13 with no shell, no package manager, and no inbound network listener. The only outbound connections are to your Plex server and plex.tv.

Pull

docker pull cplieger/plex-language-sync:latest

Also published to ghcr.io/cplieger/plex-language-sync with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.

Quick start

# Example compose for plex-language-sync. See the README for all configuration options and hardening.
services:
  plex-language-sync:
    image: ghcr.io/cplieger/plex-language-sync:latest
    container_name: plex-language-sync
    restart: unless-stopped
    stop_grace_period: 20s  # headroom over the ~10s shutdown drain so SIGKILL does not truncate the final cache save (see README)
    # Override with PUID/PGID in .env; defaults to 1000:1000.
    user: "${PUID:-1000}:${PGID:-1000}"  # must own the /config host dir

    environment:
      PLEX_URL: "http://plex:32400"  # full URL including scheme and port
      PLEX_TOKEN: "your-plex-token"  # admin token from Plex Web settings; or set PLEX_TOKEN_FILE to a Docker secret (see README)
      UPDATE_LEVEL: "show"  # show = entire show, season = current season only
      UPDATE_STRATEGY: "all"  # all = every episode, next = future episodes only

    volumes:
      - "/opt/appdata/plex-language-sync:/config"

Documentation

License

GPL-3.0-or-later. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.

Tag summary

Content type

Image

Digest

sha256:e8daa82ea

Size

4.1 MB

Last updated

about 3 hours ago

docker pull cplieger/plex-language-sync