diff --git a/mpvremote2.sh b/mpvremote2.sh deleted file mode 100755 index 961cf72..0000000 --- a/mpvremote2.sh +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/env bash - -# ============================================================================== -# GPLv3: You better join us now and share the software, motherfucker. -# Keep the code free as in freedom. -# If you're gonna sell it, give 'em the code too. -# -# WTF IS THIS? -# A quick-and-dirty "TV style" remote control for mpv over a UNIX socket. -# -# ASSUMPTIONS: -# 1. mpv is already running. -# 2. mpv was launched with: -# --input-ipc-server=/tmp/mpv-socket -# or the socket is configured in mpv.conf. -# ============================================================================== - -SOCKET="/tmp/mpv-socket" -MEDIA_DIR="$HOME/GDrive/Videos" - -if [[ ! -S "$SOCKET" ]]; then - echo "Error: Socket $SOCKET not found or mpv is not running." - exit 1 -fi - -# ------------------------------------------------------------------------------ -# Send an mpv IPC command. -# -# Usage: -# mpv-cmd "cycle" "pause" -# mpv-cmd "seek" "10" -# mpv-cmd "loadfile" "/path/to/file" "append-play" -# ------------------------------------------------------------------------------ - -mpv-cmd() { - local json_args="" - local arg - - for arg in "$@"; do - # Escape JSON string characters. - arg="${arg//\\/\\\\}" - arg="${arg//\"/\\\"}" - arg="${arg//$'\n'/\\n}" - arg="${arg//$'\r'/\\r}" - arg="${arg//$'\t'/\\t}" - - if [[ -n "$json_args" ]]; then - json_args+="," - fi - - json_args+="\"$arg\"" - done - - printf '{"command":[%s]}\n' "$json_args" | - socat -t 1 - "$SOCKET" >/dev/null 2>&1 -} - -# ------------------------------------------------------------------------------ -# Get an mpv property. -# -# Requires jq. This avoids trying to parse JSON with sed. -# ------------------------------------------------------------------------------ - -mpv-get() { - local prop="$1" - - if ! command -v jq >/dev/null 2>&1; then - echo "Error: jq is required for property queries." >&2 - return 1 - fi - - printf '{"command":["get_property","%s"]}\n' "$prop" | - socat -t 1 - "$SOCKET" 2>/dev/null | - jq -r '.data // empty' -} - -# ------------------------------------------------------------------------------ -# Queue a video. -# ------------------------------------------------------------------------------ - -queue_picker() { - echo - echo "--- Queue Media from $MEDIA_DIR ---" - - if [[ ! -d "$MEDIA_DIR" ]]; then - echo "Directory not found: $MEDIA_DIR" - return 1 - fi - - local clean_dir="${MEDIA_DIR%/}" - declare -A video_map - - local exts=( - "mp4" - "mkv" - "avi" - "webm" - ) - - local find_args=() - - for ext in "${exts[@]}"; do - if [[ ${#find_args[@]} -gt 0 ]]; then - find_args+=("-o") - fi - - find_args+=("-iname" "*.$ext") - done - - while IFS= read -r -d '' file; do - local rel_name="${file#"${clean_dir}/"}" - video_map["$rel_name"]="$file" - done < <( - find "$clean_dir" \ - -type f \ - \( "${find_args[@]}" \) \ - -print0 - ) - - if [[ ${#video_map[@]} -eq 0 ]]; then - echo "No video files found." - return 1 - fi - - local selected_key="" - - if command -v fzf >/dev/null 2>&1; then - selected_key=$( - printf '%s\n' "${!video_map[@]}" | - sort | - fzf --prompt="Select video to queue: " - ) - else - echo "Choose a file to queue (or Cancel):" - - PS3="Enter number: " - - local keys=("${!video_map[@]}") - - select choice in "${keys[@]}" "Cancel"; do - if [[ "$choice" == "Cancel" || -z "$choice" ]]; then - echo "Cancelled." - return 0 - fi - - selected_key="$choice" - break - done - fi - - if [[ -n "$selected_key" && -n "${video_map[$selected_key]:-}" ]]; then - local abs_path="${video_map[$selected_key]}" - - echo "Queuing: $(basename "$abs_path")" - - mpv-cmd "loadfile" "$abs_path" "append-play" - mpv-cmd "set_property" "pause" "no" - fi -} - -cleanup() { - if [[ -n "${old_stty:-}" ]]; then - stty "$old_stty" 2>/dev/null - else - stty sane 2>/dev/null - fi - echo -} - -# ------------------------------------------------------------------------------ -# Edit the current playlist via fzf. -# -# Enter -> skip to selected item -# Del -> remove selected item -# q/Esc/Left -> return to remote -# ------------------------------------------------------------------------------ - -edit_playlist() { - local playlist_json fzf_input selected key_pressed idx - - while true; do - playlist_json=$(mpv-get "playlist") - - if [[ -z "$playlist_json" || "$playlist_json" == "[]" ]]; then - echo "Playlist is empty." - return - fi - - fzf_input=$(printf '%s' "$playlist_json" | jq -r ' - to_entries[] | - (if .value.current == true then "▶ " else "" end) as $prefix | - "\(.key)|\($prefix)\(.value.title // (.value.filename | split("/") | last))" - ') - - if [[ -z "$fzf_input" ]]; then - echo "Playlist is empty." - return - fi - - readarray -t result < <( - printf '%s\n' "$fzf_input" | fzf \ - --delimiter='|' \ - --with-nth=2 \ - --prompt="Playlist (Enter=skip, Del=remove, Esc/q/←=back): " \ - --expect=del,left,esc,q \ - --header="Current Playlist" - ) - - key_pressed="${result[0]:-}" - selected="${result[1]:-}" - - if [[ -z "$selected" ]]; then - return - fi - - idx="${selected%%|*}" - - if [[ -z "$key_pressed" ]]; then - # Enter pressed - skip to index - mpv-cmd "set_property" "playlist-pos" "$idx" - return - elif [[ "$key_pressed" == "del" ]]; then - mpv-cmd "playlist-remove" "$idx" - # Refresh loop - continue - else - # q, esc, left - return - fi - done -} - -remote() { - local old_stty - old_stty=$(stty -g) - - trap 'exit 130' INT - trap 'exit 143' TERM - trap cleanup EXIT - - stty -echo -icanon min 1 time 0 - - echo "=== MPV Terminal Remote ===" - echo "[Space] Pause | [h/l] Seek -10s/+10s | [j/k] Vol -/+ | [s] Subtitle" - echo "[o] Open/Queue Video | [e] Edit Playlist | [n] Next Track | [p] Prev Track" - echo "[r] Repeat Current Vid | [R] Repeat Playlist | [c] Controls | [q] Quit" - echo "Listening..." - - while IFS= read -r -n1 key; do - case "$key" in - ' ') - mpv-cmd "cycle" "pause" - is_paused=$(mpv-get "pause") - - if [[ "$is_paused" == "true" ]]; then - echo ">> Video Paused..." - else - echo ">> Video Unpaused..." - fi - ;; - - c) - echo "=== MPV Terminal Remote ===" - echo "[Space] Pause | [h/l] Seek -10s/+10s | [j/k] Vol -/+ | [s] Subtitle" - echo "[o] Open/Queue Video | [e] Edit Playlist | [n] Next Track | [p] Prev Track" - echo "[r] Repeat Current Vid | [R] Repeat Playlist | [c] Controls | [q] Quit" - ;; - h) - mpv-cmd "seek" "-10" - echo ">> Seeked -10s" - ;; - - l) - mpv-cmd "seek" "10" - echo ">> Seeked +10s" - ;; - - k) - mpv-cmd "add" "volume" "5" - vol=$(mpv-get "volume") - echo ">> Volume Level: ${vol%.*}" - ;; - - j) - mpv-cmd "add" "volume" "-5" - vol=$(mpv-get "volume") - echo ">> Volume Level: ${vol%.*}" - ;; - - s) - mpv-cmd "cycle" "sub" - sub_state=$(mpv-get "sub") - - if [[ "$sub_state" == "false" || - "$sub_state" == "no" || - -z "$sub_state" ]]; then - echo ">> Subtitles Disabled..." - else - echo ">> Subtitles Enabled... ($sub_state)" - fi - ;; - - n) - mpv-cmd "playlist-next" - echo ">> Next Track" - ;; - - p) - mpv-cmd "playlist-prev" - echo ">> Prev Track" - ;; - r) - f_loop=$(mpv-get "loop-file") - - if [[ "$f_loop" == "no" || "$f_loop" == "false" || -z "$f_loop" ]]; then - mpv-cmd "set_property" "loop-file" "inf" - echo ">> Loop Current Vid: yes (inf)" - else - mpv-cmd "set_property" "loop-file" "no" - echo ">> Loop Current Vid: no" - fi - ;; - - R) - p_loop=$(mpv-get "loop-playlist") - - if [[ "$p_loop" == "no" || "$p_loop" == "false" || -z "$p_loop" ]]; then - mpv-cmd "set_property" "loop-playlist" "inf" - echo ">> Loop Current Playlist: yes (inf)" - else - mpv-cmd "set_property" "loop-playlist" "no" - echo ">> Loop Current Playlist: no" - fi - ;; - - e) - stty "$old_stty" - edit_playlist - stty -echo -icanon min 1 time 0 - echo "Listening..." - ;; - - o) - stty "$old_stty" - queue_picker - stty -echo -icanon min 1 time 0 - echo "Listening..." - ;; - - q) - echo - echo "Exiting remote." - exit 0 - ;; - esac - done -} - -remote "$@"