Record streams into hidden .live/ and publish finished files via the sweep; plugin 0.1.2 feed wording
Jellyfin indexed in-progress fragmented recordings (no duration -> seek jumped to next episode). MediaMTX now writes under <Title>/.live/; the sweep remuxes finished files into the title folder and removes the source. Feed says 'New recording' since it fires after publish. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
# - fragmented/unindexed MP4 (MediaMTX output) with good codecs: lossless remux, replaced in place
|
||||
# - anything else (HEVC, 10-bit, VFR, MKV, >1440p, >60fps): full-res re-encode -> name.mp4,
|
||||
# raw source kept in a hidden .src/ subfolder next to it (Jellyfin/copyparty hide dot-dirs)
|
||||
# - streams/<user>/<Title>/.live/<ts>.mp4 (MediaMTX writes here, hidden from Jellyfin/copyparty while live):
|
||||
# when finished -> flat MP4 written to the parent folder, the .live source deleted. One copy, and nothing
|
||||
# indexes a recording in progress.
|
||||
# - Syncthing folders (marker dir .stfolder in the folder root, receive-only): compliant files are left
|
||||
# alone (zero copies); a non-compliant file is converted to name.mp4 (name.h264.mp4 if the raw is
|
||||
# already .mp4), the raw's name is appended to .stlocal (an #include'd ignore list) so Syncthing
|
||||
@@ -66,6 +69,11 @@ find "$ROOT/streams" "$ROOT/clips" -type f \
|
||||
! -path '*/.src/*' ! -path '*/.stfolder/*' ! -path '*/.stversions/*' ! -name '*.part' -mmin +"$MINS_IDLE" -print0 2>/dev/null |
|
||||
while IFS= read -r -d '' src; do
|
||||
base="${src%.*}"; ext="${src##*.}"
|
||||
live=0
|
||||
if [[ $(basename "$(dirname "$src")") == .live ]]; then
|
||||
live=1
|
||||
base="$(dirname "$(dirname "$src")")/$(basename "${src%.*}")"
|
||||
fi
|
||||
synced=0; stroot=""
|
||||
d="$(dirname "$src")"
|
||||
while [[ $d == "$ROOT"/* ]]; do # find the Syncthing folder root, if any
|
||||
@@ -77,8 +85,14 @@ while IFS= read -r -d '' src; do
|
||||
[[ -e "$src" ]] || continue # dumped meanwhile
|
||||
|
||||
read -r verdict reason <<<"$(probe "$src")"
|
||||
case "$verdict" in ok|skip) continue ;; esac
|
||||
out="$base.mp4"
|
||||
if (( live )); then
|
||||
[[ $verdict == skip ]] && continue
|
||||
[[ $verdict == ok ]] && verdict=remux # must leave .live/ either way
|
||||
out="$base.mp4"; [[ -e "$out" ]] && { log "exists $out (leaving $src)"; continue; }
|
||||
else
|
||||
case "$verdict" in ok|skip) continue ;; esac
|
||||
out="$base.mp4"
|
||||
fi
|
||||
if (( synced )); then
|
||||
[[ $verdict == remux ]] && continue # synced + only an index issue: not worth touching
|
||||
[[ ${ext,,} == mp4 ]] && out="$base.h264.mp4" # raw is already name.mp4: don't collide
|
||||
@@ -104,7 +118,11 @@ while IFS= read -r -d '' src; do
|
||||
rc=$?
|
||||
d1=$(dur "$src"); d2=$(dur "$tmp")
|
||||
if (( rc == 0 )) && [[ -n $d1 && -n $d2 ]] && (( d2 >= d1 - 2 && d2 <= d1 + 2 )); then
|
||||
if (( synced )); then
|
||||
if (( live )); then
|
||||
mv -f "$tmp" "$out"; chown 1000:1000 "$out" 2>/dev/null
|
||||
rm -f "$src"; rmdir "$(dirname "$src")" 2>/dev/null || true
|
||||
log "done $out"; continue
|
||||
elif (( synced )); then
|
||||
rel_src="${src#"$stroot"/}"; rel_out="${out#"$stroot"/}"
|
||||
{ echo "/$rel_out"; echo "/$rel_src"; } >> "$stroot/.stlocal" # ignore our output and the raw
|
||||
chown 1000:1000 "$stroot/.stlocal" 2>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user