play_state_sync: sync across all hosts via Tailscale

Discover all HOST*_TRANSCODE_SERVERS from every configured host.
For remote hosts, rewrite localhost/127.0.0.1 in the URL to their
Tailscale IP (via resolve_tailscale_ip). Unreachable hosts are
warned and skipped — partial sync continues for reachable servers.

Adding a new host needs no script changes — just HOST*_TRANSCODE_SERVERS
in the new host conf.
This commit is contained in:
Gmer4Lfe
2026-05-30 00:23:32 -04:00
parent 1184be3e28
commit 788c04ce9d
+39 -16
View File
@@ -36,9 +36,9 @@
# CONFIGURATION (host*.conf, aliased by detect_hosts)
# ==============================================================================================
#
# HOST*_TRANSCODE_SERVERS Array of "Name|URL|APIKey|type" entries (emby/jellyfin)
# Aliased to TRANSCODE_SERVERS by detect_hosts()
# Falls back to HOST*_EMBY_URL/KEY and HOST*_JELLYFIN_URL/KEY
# HOST*_TRANSCODE_SERVERS "Name|URL|APIKey|type" entries per host (emby/jellyfin)
# All hosts are discovered automatically — no extra config needed.
# Remote host URLs have localhost rewritten to their Tailscale IP.
#
# master.conf
#
@@ -91,16 +91,17 @@ SYNC_TYPES="${PLAY_SYNC_TYPES:-Movie,Episode,Audio}"
command -v jq >/dev/null 2>&1 || { error "jq is required but not installed"; exit 1; }
acquire_lock
detect_hosts
# ── Build server list from TRANSCODE_SERVERS (aliased by detect_hosts) ────────
# ── Build server list across ALL hosts ────────────────────────────────────────
# All HOST*_TRANSCODE_SERVERS arrays are loaded into env by load_config.sh.
# For remote hosts, localhost in the URL is rewritten to their Tailscale IP.
declare -a SRV_NAME SRV_URL SRV_KEY SRV_TYPE
_srv_count=0
_my_hostname=$(hostname -s)
_add_server() {
local name="$1" url="$2" key="$3" type="$4"
[[ -z "$url" || -z "$key" ]] && return
# Skip placeholder/empty API keys
[[ "$key" == "YOUR_API_KEY"* || "$key" == "placeholder"* ]] && return
SRV_NAME[$_srv_count]="$name"
SRV_URL[$_srv_count]="$url"
@@ -109,18 +110,40 @@ _add_server() {
(( _srv_count++ ))
}
# TRANSCODE_SERVERS is aliased from HOST*_TRANSCODE_SERVERS by detect_hosts()
# Format: "ContainerName|URL|APIKey|Type"
if [[ ${#TRANSCODE_SERVERS[@]} -gt 0 ]]; then
for _entry in "${TRANSCODE_SERVERS[@]}"; do
for _varname in $(compgen -v | grep -E '^HOST[0-9]+$' | sort); do
_num="${_varname//[^0-9]/}"
_host_hostname="${!_varname}"
[[ -z "$_host_hostname" ]] && continue
_is_me=false
[[ "${_host_hostname,,}" == "${_my_hostname,,}" ]] && _is_me=true
# Resolve Tailscale IP for remote hosts
_ts_ip=""
if [[ "$_is_me" == false ]]; then
_ts_ip=$(resolve_tailscale_ip "$_host_hostname")
if [[ -z "$_ts_ip" ]]; then
log "$_host_hostname — Tailscale IP not found, skipping"
continue
fi
fi
# Load this host's TRANSCODE_SERVERS array
_srv_arr_name="HOST${_num}_TRANSCODE_SERVERS"
eval "_host_entries=(\"\${${_srv_arr_name}[@]}\")"
[[ "${#_host_entries[@]}" -eq 0 ]] && continue
for _entry in "${_host_entries[@]}"; do
IFS='|' read -r _name _url _key _type <<< "$_entry"
[[ "$_type" == "emby" || "$_type" == "jellyfin" ]] && _add_server "$_name" "$_url" "$_key" "$_type"
[[ "$_type" == "emby" || "$_type" == "jellyfin" ]] || continue
# For remote hosts rewrite localhost/127.0.0.1 → Tailscale IP
if [[ "$_is_me" == false ]]; then
_url="${_url//localhost/$_ts_ip}"
_url="${_url//127.0.0.1/$_ts_ip}"
fi
_add_server "${_name} (${_host_hostname})" "$_url" "$_key" "$_type"
done
else
# Fallback to individual vars
_add_server "${EMBY_CONTAINER:-Emby}" "${EMBY_URL:-}" "${EMBY_API_KEY:-}" "emby"
_add_server "${JELLYFIN_CONTAINER:-Jellyfin}" "${JELLYFIN_URL:-}" "${JELLYFIN_API_KEY:-}" "jellyfin"
fi
done
if [[ "$_srv_count" -lt 2 ]]; then
error "Need at least 2 media servers configured — found $_srv_count"