# Playback tools and helper # # The methods to control the mpv instance are in `src/sh/mpv.sh`. Here, # a higher-level playback functionality is provided. # Available playback commands if [ ! "${PLAYBACK_LOADED:-}" ]; then PLAYBACK_CMD_PLAY="play" PLAYBACK_CMD_QUEUE="queue" PLAYBACK_CMD_QUEUE_NEXT="queue-next" PLAYBACK_CMD_TOGGLE_PLAYBACK="toggle" PLAYBACK_CMD_PLAY_NEXT="next" PLAYBACK_CMD_PLAY_PREV="prev" PLAYBACK_CMD_SEEK_FORWARD="seekf" PLAYBACK_CMD_SEEK_BACKWARD="seekb" export PLAYBACK_CMD_PLAY PLAYBACK_CMD_QUEUE PLAYBACK_CMD_QUEUE_NEXT \ PLAYBACK_CMD_TOGGLE_PLAYBACK PLAYBACK_CMD_PLAY_NEXT \ PLAYBACK_CMD_PLAY_PREV PLAYBACK_CMD_SEEK_FORWARD PLAYBACK_CMD_SEEK_BACKWARD export PLAYBACK_LOADED=1 fi # Obtain playback command from key press # @argument $1: key __playback_cmd_from_key() { key=$1 case ",$KEYS_PLAY," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY" && return ;; esac case ",$KEYS_N_PLAY," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY" && return ;; esac case ",$KEYS_QUEUE," in *",$key,"*) echo "$PLAYBACK_CMD_QUEUE" && return ;; esac case ",$KEYS_N_QUEUE," in *",$key,"*) echo "$PLAYBACK_CMD_QUEUE" && return ;; esac case ",$KEYS_QUEUE_NEXT," in *",$key,"*) echo "$PLAYBACK_CMD_QUEUE_NEXT" && return ;; esac case ",$KEYS_N_QUEUE_NEXT," in *",$key,"*) echo "$PLAYBACK_CMD_QUEUE_NEXT" && return ;; esac case ",$KEYS_TOGGLE_PLAYBACK," in *",$key,"*) echo "$PLAYBACK_CMD_TOGGLE_PLAYBACK" && return ;; esac case ",$KEYS_N_TOGGLE_PLAYBACK," in *",$key,"*) echo "$PLAYBACK_CMD_TOGGLE_PLAYBACK" && return ;; esac case ",$KEYS_PLAY_NEXT," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY_NEXT" && return ;; esac case ",$KEYS_N_PLAY_NEXT," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY_NEXT" && return ;; esac case ",$KEYS_PLAY_PREV," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY_PREV" && return ;; esac case ",$KEYS_N_PLAY_PREV," in *",$key,"*) echo "$PLAYBACK_CMD_PLAY_PREV" && return ;; esac case ",$KEYS_SEEK_FORWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_FORWARD" && return ;; esac case ",$KEYS_N_SEEK_FORWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_FORWARD" && return ;; esac case ",$KEYS_SEEK_BACKWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_BACKWARD" && return ;; esac case ",$KEYS_N_SEEK_BACKWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_BACKWARD" && return ;; esac } # Generate playlist from MB release ID and path to decoration # @argument $1: MusicBrainz Release ID # @argument $2: Path to decoration file # @argument $3: MusicBrainz Track ID to select (optional) __generate_playlist() { printf "#EXTM3U\n" dir="$(dirname "$2")" mb_release "$1" | $JQ \ --slurpfile decofile "$2" \ --arg base "$dir" \ --arg deco "$2" \ --arg tid "${3:-}" \ '$decofile[].tracks as $filenames | . | .id as $rid | .media[] | .position as $pos | .tracks | if ($tid == "") then . else map(select(.id == $tid)) end | map({ t: [ $rid, .id, $pos, .number, .length, .title, (."artist-credit" | map([.name, .joinphrase] | join("")) | join("")), $deco ] | join("\t"), length: (.length // 0 / 1000 | round | tostring), $pos, number: .number, file: $filenames[.id] }) | map(if(.number | type == "string" and test("^[0-9]+$")) then .number |= tonumber else . end) | sort_by([.pos, .number]) | map("#EXTINF:" + .length + "," + .t + "\n" + $base + "/" + .file)[]' } # Main playback method # # @argument $1: view # @argument $2: MusicBrainz ID of current object # @argument $3: MusicBrainz ID of selected object # @argument $4: Path to decoration file # # This option controls the mpv instance via a key pressed in fzf. The key # pressed is stored in the environment variable FZF_KEY and is resolved to # the playback command through the method `__playback_cmd_from_key`. playback() { view=${1:-} mbid_current="${2:-}" mbid="${3:-}" path="${4:-}" pbcmd=$(__playback_cmd_from_key "$FZF_KEY") case "$pbcmd" in "$PLAYBACK_CMD_PLAY") [ "$path" ] || exit 0 case "$view" in "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;; "$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;; "$VIEW_PLAYLIST") mpv_play_index $((FZF_POS - 1)) >/dev/null ;; esac ;; "$PLAYBACK_CMD_QUEUE") [ "$path" ] || exit 0 case "$view" in "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null ;; "$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;; "$VIEW_PLAYLIST") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;; esac ;; "$PLAYBACK_CMD_QUEUE_NEXT") [ "$path" ] || exit 0 case "$view" in "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;; "$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_queue_next_list >/dev/null ;; "$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;; "$VIEW_PLAYLIST") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;; esac ;; "$PLAYBACK_CMD_TOGGLE_PLAYBACK") mpv_toggle_pause ;; "$PLAYBACK_CMD_PLAY_NEXT") mpv_next ;; "$PLAYBACK_CMD_PLAY_PREV") mpv_prev ;; "$PLAYBACK_CMD_SEEK_FORWARD") mpv_seek_forward ;; "$PLAYBACK_CMD_SEEK_BACKWARD") mpv_seek_backward ;; esac }