transcode manager now handles multiple media servers

This commit is contained in:
2026-04-20 18:17:13 -04:00
parent e83473ab8e
commit 1a16ca02a9
5 changed files with 255 additions and 69 deletions
+105 -53
View File
@@ -49,15 +49,11 @@ success "Running as root"
acquire_lock "wait"
# Select correct Emby instance for session display
detect_hosts
if [[ "$LOCAL_SERVER_NAME" == "$HOST1" ]]; then
EMBY_URL="${HOST1_EMBY_URL}"
EMBY_API_KEY="${HOST1_EMBY_API_KEY}"
else
EMBY_URL="${HOST2_EMBY_URL}"
EMBY_API_KEY="${HOST2_EMBY_API_KEY}"
# Primary server for container running check — first entry in TRANSCODE_SERVERS
# Full session display loops over all entries in the array
if [[ "${#TRANSCODE_SERVERS[@]}" -gt 0 ]]; then
IFS='|' read -r PRIMARY_CONTAINER _ _ _ <<< "${TRANSCODE_SERVERS[0]}"
TRANSCODE_EMBY_CONTAINER="${PRIMARY_CONTAINER:-Emby}"
fi
case "$TRANSCODE_MANAGER_MODE" in
@@ -335,63 +331,93 @@ FLIP_COUNT=$(get_flip_count)
echo ""
echo "━━━ $ICON_EMBY Active Emby Sessions ━━━"
# -----------------------------------------------------------------------------------------------
# ━━━ $ICON_EMBY Active Transcode Sessions ━━━
# Queries all configured servers in TRANSCODE_SERVERS array
# Aggregates sessions, counts, and storage state across all servers
# -----------------------------------------------------------------------------------------------
echo ""
echo "━━━ $ICON_EMBY Active Transcode Sessions ━━━"
TOTAL_SESSIONS=0
LIVE_TV=0
TRANSCODING=0
DIRECT=0
ANY_SERVER_RUNNING=false
if [[ -z "$EMBY_API_KEY" ]]; then
info "EMBY_API_KEY not set in Master.conf — skipping session display"
elif [[ "$EMBY_RUNNING" == false ]]; then
info "Emby not running — no sessions"
else
SESSION_DATA=$(emby_api "Sessions" 2>/dev/null)
for server_entry in "${TRANSCODE_SERVERS[@]}"; do
# Parse entry — ContainerName|URL|APIKey|Type
IFS='|' read -r SRV_CONTAINER SRV_URL SRV_KEY SRV_TYPE <<< "$server_entry"
# Skip placeholder entries
if [[ "$SRV_KEY" == *"api-key"* ]] || [[ "$SRV_KEY" == *"token"* && ${#SRV_KEY} -lt 20 ]]; then
log "Skipping $SRV_CONTAINER — placeholder API key"
continue
fi
# Check if container is running
if ! docker inspect "$SRV_CONTAINER" --format '{{.State.Running}}' 2>/dev/null | grep -q "true"; then
info "$ICON_CONTAINERS $SRV_CONTAINER — not running, skipping"
continue
fi
ANY_SERVER_RUNNING=true
# Check API reachability
if ! check_api "$SRV_URL" "$SRV_CONTAINER" 5; then
warn "$SRV_CONTAINER — API unreachable, skipping (container up but API not responding)"
continue
fi
# Query sessions based on server type
case "$SRV_TYPE" in
emby|jellyfin)
SESSION_DATA=$(curl -sf --max-time 10 \
-H "X-Emby-Token: $SRV_KEY" \
"${SRV_URL}/Sessions" 2>/dev/null)
;;
plex)
SESSION_DATA=$(curl -sf --max-time 10 \
-H "X-Plex-Token: $SRV_KEY" \
"${SRV_URL}/status/sessions" 2>/dev/null)
;;
*)
warn "Unknown server type '$SRV_TYPE' for $SRV_CONTAINER — skipping"
continue
;;
esac
if [[ -z "$SESSION_DATA" ]] || ! command -v jq >/dev/null 2>&1; then
warn "Could not retrieve session data — check EMBY_URL and EMBY_API_KEY"
else
# Count sessions
TOTAL_SESSIONS=$(echo "$SESSION_DATA" | \
warn "Could not retrieve session data from $SRV_CONTAINER"
continue
fi
# Count sessions (Emby/Jellyfin format)
if [[ "$SRV_TYPE" == "emby" || "$SRV_TYPE" == "jellyfin" ]]; then
SRV_TOTAL=$(echo "$SESSION_DATA" | \
jq '[.[] | select(.NowPlayingItem != null)] | length' 2>/dev/null || echo 0)
LIVE_TV=$(echo "$SESSION_DATA" | \
SRV_LIVE=$(echo "$SESSION_DATA" | \
jq '[.[] | select(.NowPlayingItem != null) | select(.NowPlayingItem.Type == "LiveTv" or .NowPlayingItem.Type == "TvChannel")] | length' \
2>/dev/null || echo 0)
TRANSCODING=$(echo "$SESSION_DATA" | \
SRV_TRANSCODE=$(echo "$SESSION_DATA" | \
jq '[.[] | select(.NowPlayingItem != null) | select(.PlayState.PlayMethod == "Transcode")] | length' \
2>/dev/null || echo 0)
DIRECT=$(echo "$SESSION_DATA" | \
SRV_DIRECT=$(echo "$SESSION_DATA" | \
jq '[.[] | select(.NowPlayingItem != null) | select(.PlayState.PlayMethod != "Transcode")] | length' \
2>/dev/null || echo 0)
echo " $ICON_EMBY Total: $TOTAL_SESSIONS | $ICON_RAM Live TV: $LIVE_TV | $ICON_SYNC Transcoding: $TRANSCODING | $ICON_DONE Direct: $DIRECT"
echo ""
TOTAL_SESSIONS=$(( TOTAL_SESSIONS + SRV_TOTAL ))
LIVE_TV=$(( LIVE_TV + SRV_LIVE ))
TRANSCODING=$(( TRANSCODING + SRV_TRANSCODE ))
DIRECT=$(( DIRECT + SRV_DIRECT ))
if [[ "$TOTAL_SESSIONS" -gt 0 ]]; then
# Display server header if more than one server configured and running
if [[ "${#TRANSCODE_SERVERS[@]}" -gt 1 ]]; then
echo " $ICON_EMBY $SRV_CONTAINER$SRV_TOTAL streams"
fi
# Storage state — count session folders on each location
# Emby folder names don't match API session IDs — per-session location not possible
# Split state shows when symlink has flipped mid-session
TRANSCODE_TEMP="transcoding-temp"
RAM_SESSION_COUNT=$(find "$RAMDISK_PATH/$TRANSCODE_TEMP" \
-mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
SSD_SESSION_COUNT=$(find "$TRANSCODE_SSD/$TRANSCODE_TEMP" \
-mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
if [[ "$RAM_SESSION_COUNT" -gt 0 && "$SSD_SESSION_COUNT" -gt 0 ]]; then
warn "$ICON_WARN Split state — $RAM_SESSION_COUNT folder(s) on ramdisk / $SSD_SESSION_COUNT on SSD"
warn "Older sessions remain on original location until they end naturally"
echo " $ICON_LINK Storage: $ICON_RAM ramdisk ($RAM_SESSION_COUNT) + $ICON_DISK SSD ($SSD_SESSION_COUNT)"
elif [[ "$RAM_SESSION_COUNT" -gt 0 ]]; then
echo " $ICON_LINK Storage: $ICON_RAM ramdisk"
elif [[ "$SSD_SESSION_COUNT" -gt 0 ]]; then
echo " $ICON_LINK Storage: $ICON_DISK SSD"
else
echo " $ICON_LINK Storage: $ICON_INFO no transcode folders found"
fi
echo ""
# List each active session
# List each active session
if [[ "$SRV_TOTAL" -gt 0 ]]; then
while IFS= read -r session; do
USER=$(echo "$session" | jq -r '.UserName // "Unknown"' 2>/dev/null)
TITLE=$(echo "$session" | jq -r '.NowPlayingItem.Name // "Unknown"' 2>/dev/null)
@@ -402,13 +428,39 @@ else
METHOD_LABEL=$(get_play_method_label "$PLAY_METHOD")
echo " $ICON_EMBY $(printf '%-12s' "$USER")$(printf '%-30s' "$TITLE")$(printf '%-10s' "$MEDIA_LABEL")$METHOD_LABEL"
done < <(echo "$SESSION_DATA" | \
jq -c '.[] | select(.NowPlayingItem != null)' 2>/dev/null)
else
info "No active streams"
fi
fi
done
# Totals header — shown after all servers
echo ""
echo " $ICON_EMBY Total: $TOTAL_SESSIONS | $ICON_RAM Live TV: $LIVE_TV | $ICON_SYNC Transcoding: $TRANSCODING | $ICON_DONE Direct: $DIRECT"
# Storage state — based on total ramdisk/SSD session folders
if [[ "$TOTAL_SESSIONS" -gt 0 ]]; then
TRANSCODE_TEMP="transcoding-temp"
RAM_SESSION_COUNT=$(find "$RAMDISK_PATH/$TRANSCODE_TEMP" \
-mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
SSD_SESSION_COUNT=$(find "$TRANSCODE_SSD/$TRANSCODE_TEMP" \
-mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
if [[ "$RAM_SESSION_COUNT" -gt 0 && "$SSD_SESSION_COUNT" -gt 0 ]]; then
warn "$ICON_WARN Split state — $RAM_SESSION_COUNT folder(s) on ramdisk / $SSD_SESSION_COUNT on SSD"
warn "Older sessions remain on original location until they end naturally"
echo " $ICON_LINK Storage: $ICON_RAM ramdisk ($RAM_SESSION_COUNT) + $ICON_DISK SSD ($SSD_SESSION_COUNT)"
elif [[ "$RAM_SESSION_COUNT" -gt 0 ]]; then
echo " $ICON_LINK Storage: $ICON_RAM ramdisk"
elif [[ "$SSD_SESSION_COUNT" -gt 0 ]]; then
echo " $ICON_LINK Storage: $ICON_DISK SSD"
fi
fi
if [[ "$ANY_SERVER_RUNNING" == false && "$TRANSCODE_CHECK_EMBY" == true ]]; then
info "No configured media servers are running — skipping threshold checks"
EMBY_RUNNING=false
fi
# -----------------------------------------------------------------------------------------------
@@ -455,7 +507,7 @@ case "$TRANSCODE_MANAGER_MODE" in
info "$ICON_GEAR Mode: SMART — auto threshold management"
if [[ "$EMBY_RUNNING" == false ]]; then
info "Emby not running — skipping threshold checks"
info "No media servers running — skipping threshold checks"
elif [[ "$RAMDISK_HEALTHY" == false ]]; then
info "Ramdisk unavailable — staying on SSD until ramdisk recovers"