Post

WatchState

WatchState syncs play state (watched/unwatched and resume progress) between Plex, Jellyfin and Emby without relying on third-party services. It pulls changes from the media servers through scheduled imports or webhooks and pushes them to the others one-way or two-way, maps the users of each server, keeps portable backups of the play state and audits mismatched records with Media Health. This script builds the PHP backend and the web UI from source and serves them with nginx, PHP-FPM and Redis.

WatchState
In Development
This script is currently in active development and may be unstable or incomplete. Use in production environments is not recommended.

Installation

Default install:

1
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/watchstate.sh)"
CPU: 2 cores RAM: 2048 MB Disk: 6 GB OS: Debian 13

Notes

There is no default account. The first visit to http://[IP]:8080 asks for a system user and password, and anyone who reaches the port can set them until then, so do it right after the install. A forgotten login is cleared with: runuser -u www-data -- php /opt/watchstate/bin/console system:resetpassword, after which the next visit asks for a new one.
Add Plex, Jellyfin or Emby under Backends with the server URL and an API token (the help button in the top-right corner walks through one-way and two-way sync), then enable the Import and Export tasks under Tasks: both are off by default. For real-time sync, paste the webhook URL shown on the Backends page into each media server.
Settings (WS_* variables from the FAQ) are edited on the Env page of the web UI or in /opt/watchstate_data/config/.env; the database, backups and logs live in /opt/watchstate_data as well and survive updates.
Web UI and worker run as www-data. Run console commands from the Console page of the web UI or as www-data (runuser -u www-data -- php /opt/watchstate/bin/console ); run as root, they leave root-owned files in /opt/watchstate_data that WatchState can no longer write.
The built-in player and file checks read media files directly. They only work if the media is mounted into the container under the same paths the media servers use.

Web Interface

Port: 8080

Source code
Loading...