Jellyfin + Plex Plex+ Emby Emby + Docker+ Podman+ Unraid+ WatchState

在多个媒体服务器间同步用户播放状态,无需第三方服务

WatchState 作为独立容器中介,通过导入任务与 webhook 双通道采集 Jellyfin/Plex/Emby 的播放事件并双向同步

✓ 多服务器双向同步✓ 支持便携格式备份 ✕ 需自行管理容器权限

方案简介

WatchState 是一个开源自托管工具,核心目标是同步你的多个媒体后端(Jellyfin、Plex、Emby)之间用户的播放状态,且不依赖任何第三方服务。适合同时运行多个媒体服务器、希望观看进度/已看记录在各平台保持一致的自托管家庭影院用户。

亮点与能力

  • 通过 identities 支持多用户
  • 同步后端播放状态(many-to-manyone-way)。
  • 将后端播放状态备份为 portable 格式。
  • 接收来自媒体后端的 webhook 事件。
  • 通过 Media Health 发现记录问题。
  • 搜索你的后端元数据。
  • 通过 webhook 或计划任务同步观看进度/播放状态。

组成与分工

  • WatchState:核心同步工具,以 Docker 容器运行,提供 WebUI(端口 8080)、数据库与同步任务。
  • Jellyfin / Plex / Emby:媒体服务器后端,作为播放状态的数据来源与同步目标,可向 WatchState 发送 webhook 事件。
  • Docker / Docker Compose:推荐的部署方式,镜像为 ghcr.io/arabcoders/watchstate:latest
  • Podman:可作为 Docker 替代,将 user 设为 0:0 由 Podman 映射到运行用户。
  • Unraid Community Applications:Unraid 用户可直接搜索 watchstate 预配置安装。

前置要求

  • Docker(或 Podman)运行环境;Unraid 用户可使用 Community Applications 插件。
  • 一个用于存储数据的工作目录(如 data),容器以非 root 运行,需保证对该目录有写权限。
  • 容器默认监听 8080 端口。

实施步骤

1. 创建数据目录

首先创建一个目录用于存储数据,按照本教程在工作目录创建名为 data 的目录。

2a. 通过 compose 文件安装

data 目录旁创建 compose.yaml,内容如下:

yaml
services:
watchstate:
image: ghcr.io/arabcoders/watchstate:latest

To change the user/group id associated with the tool change the following line.

user: "${UID:-1000}:${UID:-1000}"
container_name: watchstate
restart: unless-stopped
ports:

  • "8080:8080" # The port which the watchstate will listen on.

volumes:

  • ./data:/config:rw # mount ./data in current directory to container /config directory.

运行容器:

bash
mkdir -p ./data && docker compose up -d

2b. 通过 docker 命令安装

bash
mkdir -p ./data && docker run -itd --name watchstate \
--user "${UID:-1000}:${GID:-${UID:-1000}}" \
--restart unless-stopped -p 8080:8080 \
-v ./data:/config:rw \
ghcr.io/arabcoders/watchstate:latest

3. 添加后端

启动容器后访问 http://localhost:8080 进入 WebUI。首次访问会提示创建系统用户(一次性操作)。点击右上角帮助按钮,选择 one-way 或 two-way 同步指南,按指引添加后端。

使用与配置要点

工具支持三种从后端导入数据的方法:

  • Scheduled Tasks(计划任务):定时从后端拉取数据。
  • On demand(按需):手动运行导入任务按需拉取。
  • Webhooks:接收后端事件并据此更新数据库。
即使所有后端都支持 webhook,也请保持导入任务启用,它可以拾取错过的事件。

注意事项与常见问题

  • user:--user 需匹配 data 目录所有者;容器以 rootless 运行,无法写目录时会退出。
  • 不建议以 root 运行容器;若启动失败可尝试 user: "0:0",若成功说明是权限问题。
  • Unraid 手动安装需在高级标签 Extra Parameters 中加 --user 99:100;若已用其他用户 ID 创建文件,运行 chown -R 99:100 /mnt/user/appdata/watchstate
  • 使用 Podman 时将 compose 中的 user 设为 0:0,容器看似以 root 运行但 Podman 会映射到实际用户。
  • v1.8.5+ 支持路径匹配:当后端共享相同媒体文件但外部 ID 不可靠/不一致时,可用基于媒体路径的 GUID 进行匹配。
  • Media Health 取代了旧的独立 parity、duplicate-reference、file-integrity 视图,统一审计元数据覆盖、GUID 冲突、重复引用等问题。

优缺点

  • ✓ 多服务器双向同步
  • ✓ 支持便携格式备份
  • ✕ 需自行管理容器权限

出处

本方案挖掘自开源项目 arabcoders/watchstate,方案内容与实施命令均来自其 README 原文。

方案出处
arabcoders/watchstate:Self-hosted service to sync your plex, jellyfin and emby play state. without rel
1542 star Self-hosted service to sync your plex, jellyfin and emby play state. without relying on 3rd-party external services.

本方案由真实开源项目挖掘整理,实施命令均来自其 README 原文,安装使用请遵循项目开源协议。