Fix transcode session detection for Live TV and Direct Stream

HLS segments are written atomically so lsof never sees them as open.
Cleanup now shows "Active" count (too-young files) which correctly
reflects Live TV / Direct Stream segments. Manager session count now
counts flat file prefixes in addition to subdirs.
This commit is contained in:
Gmer4Lfe
2026-06-14 11:24:21 -04:00
parent a2bcd58f78
commit df18657183
2 changed files with 31 additions and 14 deletions
+15 -7
View File
@@ -172,20 +172,24 @@ fi
cleanup_location() { cleanup_location() {
local location="$1" label="$2" max_age="$3" local location="$1" label="$2" max_age="$3"
local files_removed=0 bytes_freed=0 files_skipped=0 files_active=0 files_streaming=0 local files_removed=0 bytes_freed=0 files_skipped=0 files_active=0 files_streaming=0 files_too_young=0
if [[ ! -d "$location" ]]; then if [[ ! -d "$location" ]]; then
log "$label does not exist — skipping" log "$label does not exist — skipping"
LOCATION_REMOVED=0 LOCATION_FREED="0B" LOCATION_SKIPPED=0 LOCATION_ACTIVE=0 LOCATION_STREAMING=0 LOCATION_REMOVED=0 LOCATION_FREED="0B" LOCATION_SKIPPED=0 LOCATION_ACTIVE=0 LOCATION_STREAMING=0 LOCATION_TOO_YOUNG=0
return return
fi fi
local file_count local file_count eligible_count
file_count=$(find "$location" -type f 2>/dev/null | wc -l) file_count=$(find "$location" -type f 2>/dev/null | wc -l)
log "$label: $file_count files to scan (age threshold: ${max_age}min)" eligible_count=$(find "$location" -type f -mmin +"$max_age" 2>/dev/null | wc -l)
files_too_young=$(( file_count - eligible_count ))
log "$label: $file_count files ($eligible_count eligible, $files_too_young < ${max_age}min)"
# Build in-memory open file map — O(1) lookup per file # Build in-memory open file map — O(1) lookup per file
# One lsof call per location — never per file # One lsof call per location — never per file
# Note: HLS/remux segments (Live TV, Direct Stream) are written atomically and immediately
# closed — lsof will not detect them. The age check is the effective guard for those files.
declare -A OPEN_FILES_MAP declare -A OPEN_FILES_MAP
if [[ "$LSOF_AVAILABLE" == true ]]; then if [[ "$LSOF_AVAILABLE" == true ]]; then
log "Building open file map for $label..." log "Building open file map for $label..."
@@ -245,20 +249,21 @@ cleanup_location() {
freed_human="0B" freed_human="0B"
fi fi
log "$label — removed $files_removed files ($freed_human freed) | streaming: $files_streaming | aged+open: $files_active | skipped: $files_skipped" log "$label — removed $files_removed ($freed_human) | active(fresh): $files_too_young | streaming(lsof): $files_streaming | protected(old+open): $files_active | skipped: $files_skipped"
LOCATION_REMOVED=$files_removed LOCATION_REMOVED=$files_removed
LOCATION_FREED=$freed_human LOCATION_FREED=$freed_human
LOCATION_SKIPPED=$files_skipped LOCATION_SKIPPED=$files_skipped
LOCATION_ACTIVE=$files_active LOCATION_ACTIVE=$files_active
LOCATION_STREAMING=$files_streaming LOCATION_STREAMING=$files_streaming
LOCATION_TOO_YOUNG=$files_too_young
} }
# ============================================================================================== # ==============================================================================================
# ━━━ Transcode Cleanup ━━━ # ━━━ Transcode Cleanup ━━━
# ============================================================================================== # ==============================================================================================
START=$(date +%s) START=$(date +%s)
TOTAL_REMOVED=0 TOTAL_SKIPPED=0 TOTAL_ACTIVE=0 TOTAL_STREAMING=0 TOTAL_REMOVED=0 TOTAL_SKIPPED=0 TOTAL_ACTIVE=0 TOTAL_STREAMING=0 TOTAL_TOO_YOUNG=0
RAMDISK_FREED="0B" SSD_FREED="0B" RAMDISK_FREED="0B" SSD_FREED="0B"
# Cleanup ramdisk # Cleanup ramdisk
@@ -268,6 +273,7 @@ if mountpoint -q "$RAMDISK_PATH" 2>/dev/null; then
TOTAL_SKIPPED=$(( TOTAL_SKIPPED + LOCATION_SKIPPED )) TOTAL_SKIPPED=$(( TOTAL_SKIPPED + LOCATION_SKIPPED ))
TOTAL_ACTIVE=$(( TOTAL_ACTIVE + LOCATION_ACTIVE )) TOTAL_ACTIVE=$(( TOTAL_ACTIVE + LOCATION_ACTIVE ))
TOTAL_STREAMING=$(( TOTAL_STREAMING + LOCATION_STREAMING )) TOTAL_STREAMING=$(( TOTAL_STREAMING + LOCATION_STREAMING ))
TOTAL_TOO_YOUNG=$(( TOTAL_TOO_YOUNG + LOCATION_TOO_YOUNG ))
RAMDISK_FREED=$LOCATION_FREED RAMDISK_FREED=$LOCATION_FREED
else else
log "Ramdisk not mounted — skipping ramdisk cleanup" log "Ramdisk not mounted — skipping ramdisk cleanup"
@@ -280,6 +286,7 @@ if [[ -d "$TRANSCODE_SSD" ]]; then
TOTAL_SKIPPED=$(( TOTAL_SKIPPED + LOCATION_SKIPPED )) TOTAL_SKIPPED=$(( TOTAL_SKIPPED + LOCATION_SKIPPED ))
TOTAL_ACTIVE=$(( TOTAL_ACTIVE + LOCATION_ACTIVE )) TOTAL_ACTIVE=$(( TOTAL_ACTIVE + LOCATION_ACTIVE ))
TOTAL_STREAMING=$(( TOTAL_STREAMING + LOCATION_STREAMING )) TOTAL_STREAMING=$(( TOTAL_STREAMING + LOCATION_STREAMING ))
TOTAL_TOO_YOUNG=$(( TOTAL_TOO_YOUNG + LOCATION_TOO_YOUNG ))
SSD_FREED=$LOCATION_FREED SSD_FREED=$LOCATION_FREED
else else
log "SSD fallback not found — skipping SSD cleanup" log "SSD fallback not found — skipping SSD cleanup"
@@ -308,7 +315,8 @@ echo "$ICON_HOST Identity: $MY_ID ($LOCAL_SERVER_NAME)"
echo "$ICON_RAM Ramdisk freed: $RAMDISK_FREED" echo "$ICON_RAM Ramdisk freed: $RAMDISK_FREED"
echo "$ICON_DISK SSD freed: $SSD_FREED" echo "$ICON_DISK SSD freed: $SSD_FREED"
echo "$ICON_TRASH Removed: $TOTAL_REMOVED files" echo "$ICON_TRASH Removed: $TOTAL_REMOVED files"
echo "$ICON_RUNNING Streaming: $TOTAL_STREAMING files (open by Emby — untouched)" echo "$ICON_RUNNING Active: $TOTAL_TOO_YOUNG files (< ${TRANSCODE_MAX_AGE}min old — Live TV / Direct Stream segments)"
echo "$ICON_RUNNING Streaming: $TOTAL_STREAMING files (open file handle — long-running transcode)"
echo "$ICON_SHIELD Protected: $TOTAL_ACTIVE aged files saved by open-file check" echo "$ICON_SHIELD Protected: $TOTAL_ACTIVE aged files saved by open-file check"
echo "$ICON_TRASH Skipped: $TOTAL_SKIPPED files" echo "$ICON_TRASH Skipped: $TOTAL_SKIPPED files"
echo "$ICON_TIME Duration: $(format_duration $(( END - START )))" echo "$ICON_TIME Duration: $(format_duration $(( END - START )))"
+16 -7
View File
@@ -501,22 +501,31 @@ for server_entry in "${TRANSCODE_SERVERS[@]}"; do
done done
# Storage state # Storage state
RAM_SESSION_COUNT=$(find "$RAMDISK_PATH/transcoding-temp" \ # Sessions may use subdirectories (legacy transcode) or flat files (Live TV / Direct Stream HLS).
-mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l) # Count both: subdirs per-session, and unique hex session ID prefixes for flat files.
SSD_SESSION_COUNT=$(find "$TRANSCODE_SSD/transcoding-temp" \ _count_sessions() {
-mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l) local base="$1/transcoding-temp"
local _dirs _flat
_dirs=$(find "$base" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l)
_flat=$(find "$base" -maxdepth 1 -type f -printf '%f\n' 2>/dev/null | \
grep -oE '^[0-9a-f]{16,}' | sort -u | wc -l)
echo $(( _dirs + _flat ))
}
RAM_SESSION_COUNT=$(_count_sessions "$RAMDISK_PATH")
SSD_SESSION_COUNT=$(_count_sessions "$TRANSCODE_SSD")
unset -f _count_sessions
if [[ "$TOTAL_SESSIONS" -gt 0 ]]; then if [[ "$TOTAL_SESSIONS" -gt 0 ]]; then
echo "" echo ""
echo " $ICON_EMBY Total: $TOTAL_SESSIONS | Live TV: $LIVE_TV | Transcoding: $TRANSCODING | Direct: $DIRECT" echo " $ICON_EMBY Total: $TOTAL_SESSIONS | Live TV: $LIVE_TV | Transcoding: $TRANSCODING | Direct: $DIRECT"
if [[ "$RAM_SESSION_COUNT" -gt 0 && "$SSD_SESSION_COUNT" -gt 0 ]]; then if [[ "$RAM_SESSION_COUNT" -gt 0 && "$SSD_SESSION_COUNT" -gt 0 ]]; then
warn "Split state — $RAM_SESSION_COUNT folder(s) ramdisk / $SSD_SESSION_COUNT SSD" warn "Split state — $RAM_SESSION_COUNT session(s) ramdisk / $SSD_SESSION_COUNT SSD"
warn "Older sessions remain on original location until they end naturally" warn "Older sessions remain on original location until they end naturally"
elif [[ "$RAM_SESSION_COUNT" -gt 0 ]]; then elif [[ "$RAM_SESSION_COUNT" -gt 0 ]]; then
log "Storage: ramdisk ($RAM_SESSION_COUNT sessions)" log "Storage: ramdisk ($RAM_SESSION_COUNT session(s))"
elif [[ "$SSD_SESSION_COUNT" -gt 0 ]]; then elif [[ "$SSD_SESSION_COUNT" -gt 0 ]]; then
log "Storage: SSD ($SSD_SESSION_COUNT sessions)" log "Storage: SSD ($SSD_SESSION_COUNT session(s))"
fi fi
fi fi