feat(plum): ✨ add release/quality switching commands
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
6680cc6e7f
commit
71bed108a9
1 changed files with 61 additions and 1 deletions
|
|
@ -166,6 +166,43 @@ build_resume_playlist() { # <showdir> <resume-path> -> writes $PLAYLIST from tha
|
|||
rm -f "$PLAYLIST.all"
|
||||
}
|
||||
|
||||
# --- release/quality switching ---------------------------------------------
|
||||
json_str() { python3 -c "import json,sys; print(json.dumps(sys.argv[1]))" "$1"; }
|
||||
cur_path() { getprop path | sed 's/^"//; s/"$//'; } # strip the JSON quotes
|
||||
se_of() { printf '%s' "$1" | grep -oiE 's[0-9]+e[0-9]+' | head -1; }
|
||||
showdir_of() { # <path> -> $MEDIA_ROOT/<category>/<show>
|
||||
local p="$1" rel cat show
|
||||
case "$p" in "$MEDIA_ROOT"/*) rel="${p#"$MEDIA_ROOT"/}" ;; *) return 1 ;; esac
|
||||
cat="${rel%%/*}"; rel="${rel#*/}"; show="${rel%%/*}"
|
||||
[ -n "$cat" ] && [ -n "$show" ] || return 1
|
||||
printf '%s/%s/%s\n' "$MEDIA_ROOT" "$cat" "$show"
|
||||
}
|
||||
rel_label() { # <a path within the release> -> "720p x264"
|
||||
local q c
|
||||
q=$(printf '%s' "$1" | grep -oiE '2160p|1080p|720p|480p' | head -1)
|
||||
c=$(printf '%s' "$1" | grep -oiE 'x265|hevc|x264|av1' | head -1)
|
||||
printf '%s%s' "${q:-SD}" "${c:+ $c}"
|
||||
}
|
||||
# JSON list of release subtrees of the current show that contain the current
|
||||
# episode (so movies / partial sets are excluded). [{id,label,current}].
|
||||
releases_json() {
|
||||
local cp sd sxe out="[" first=1 d mf id label curflag
|
||||
cp=$(cur_path); [ -n "$cp" ] || { echo "[]"; return; }
|
||||
sd=$(showdir_of "$cp") || { echo "[]"; return; }
|
||||
sxe=$(se_of "$cp")
|
||||
while IFS= read -r d; do
|
||||
[ -n "$d" ] || continue
|
||||
if [ -n "$sxe" ]; then mf=$(find "$d" -type f -iregex "$VIDEO_RE" -iname "*$sxe*" 2>/dev/null | head -1)
|
||||
else mf=$(find "$d" -type f -iregex "$VIDEO_RE" 2>/dev/null | head -1); fi
|
||||
[ -n "$mf" ] || continue
|
||||
id=$(basename "$d"); label=$(rel_label "$mf")
|
||||
case "$cp" in "$d"/*) curflag=true ;; *) curflag=false ;; esac
|
||||
[ $first -eq 1 ] || out="$out,"; first=0
|
||||
out="$out{\"id\":$(json_str "$id"),\"label\":$(json_str "$label"),\"current\":$curflag}"
|
||||
done < <(find "$sd" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort)
|
||||
echo "$out]"
|
||||
}
|
||||
|
||||
status_json() {
|
||||
if [ ! -S "$SOCK" ]; then echo '{"playing":false}'; return; fi
|
||||
printf '{"playing":true,"paused":%s,"title":%s,"volume":%s,"position":%s,"duration":%s,"playlist_pos":%s,"playlist_count":%s}\n' \
|
||||
|
|
@ -225,6 +262,29 @@ case "$cmd" in
|
|||
goto-ep)
|
||||
[ $# -ge 1 ] || die "usage: black-tv goto-ep <index 0-based>"
|
||||
setprop playlist-pos "$1"; echo "playlist-pos=$(getprop playlist-pos)" ;;
|
||||
releases)
|
||||
releases_json ;;
|
||||
switch)
|
||||
# switch the CURRENT episode to another release at the same timestamp, then
|
||||
# continue the rest of the series in that release.
|
||||
[ $# -ge 1 ] || die "usage: black-tv switch <release-id>"
|
||||
[ -S "$SOCK" ] || die "nothing playing"
|
||||
cp=$(cur_path); [ -n "$cp" ] || die "nothing playing"
|
||||
pos=$(getprop time-pos); pos="${pos%.*}"; [ -n "$pos" ] || pos=0
|
||||
sxe=$(se_of "$cp"); [ -n "$sxe" ] || die "current item has no SxxEyy to map"
|
||||
sd=$(showdir_of "$cp") || die "cannot locate show dir for current item"
|
||||
td="$sd/$1"; [ -d "$td" ] || die "release not found: $1"
|
||||
tep=$(find "$td" -type f -iregex "$VIDEO_RE" -iname "*$sxe*" 2>/dev/null | head -1)
|
||||
[ -n "$tep" ] || die "release '$1' has no $sxe"
|
||||
# seamless: open the target file already positioned at the saved second
|
||||
ipc "{\"command\":[\"loadfile\",$(json_str "$tep"),\"replace\",\"start=$pos\"]}" >/dev/null
|
||||
# queue the rest of the series in the target release after this episode
|
||||
find "$td" -type f -iregex "$VIDEO_RE" ! -ipath '*/Specials/*' ! -ipath '*/Extras/*' | sort > "$PLAYLIST.all"
|
||||
start=$(grep -nF "$tep" "$PLAYLIST.all" | head -1 | cut -d: -f1)
|
||||
if [ -n "$start" ]; then tail -n +"$((start + 1))" "$PLAYLIST.all" > "$PLAYLIST"; else : > "$PLAYLIST"; fi
|
||||
[ -s "$PLAYLIST" ] && ipc "{\"command\":[\"loadlist\",$(json_str "$PLAYLIST"),\"append\"]}" >/dev/null
|
||||
rm -f "$PLAYLIST.all"
|
||||
echo "switched to $(rel_label "$tep") at ${pos}s" ;;
|
||||
watched)
|
||||
[ -f "$WATCHLOG" ] || { echo "[]"; exit 0; }
|
||||
if [ $# -ge 1 ]; then grep -iF "$1" "$WATCHLOG" | tail -100; else tail -100 "$WATCHLOG"; fi ;;
|
||||
|
|
@ -239,5 +299,5 @@ case "$cmd" in
|
|||
stop) sudo systemctl stop "$UNIT" 2>/dev/null || true; sudo pkill -x mpv 2>/dev/null || true; rm -f "$SOCK"; echo stopped ;;
|
||||
status) status_json ;;
|
||||
ensure-display) ensure_display; echo "display ready: $(cat /sys/class/drm/card0-${CONNECTOR}/status 2>/dev/null)" ;;
|
||||
*) die "usage: black-tv {play <path>|play-show <q> [S] [E]|resume-show <q>|enqueue <x>|goto-ep N|pause|resume|toggle|vol N|seek S|next|prev|stop|status|watched [q]|ensure-display}" ;;
|
||||
*) die "usage: black-tv {play <path>|play-show <q> [S] [E]|resume-show <q>|enqueue <x>|goto-ep N|releases|switch <rel>|pause|resume|toggle|vol N|seek S|next|prev|stop|status|watched [q]|ensure-display}" ;;
|
||||
esac
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue