Skip to content

Instantly share code, notes, and snippets.

@kelvinauta
Created August 17, 2025 06:04
Show Gist options
  • Select an option

  • Save kelvinauta/7bfd6ddc81ee4050210592c29d9e0edf to your computer and use it in GitHub Desktop.

Select an option

Save kelvinauta/7bfd6ddc81ee4050210592c29d9e0edf to your computer and use it in GitHub Desktop.
Search and select videos from a YouTube playlist using fzf to play it with mpv
#!/usr/bin/env bash
# Require: yt-dlp, jq, mpv, curl, chafa, fzf
# Description:
# Enter a YouTube playlist URL (save json in /tmp/playlist_title.json)
# Search and select the video titles with fzf
# Play the selected video with mpv
# When the video ends, open fzf again to select the next video
# Author: Kelvinauta | This code was created 100% by a human
trap " exit 1" SIGINT EXIT
INFINITE=1 # set to 0 if you don't want to open fzf again
input="$1"
_help="use: $(basename "$0") <url_youtube_playlist | tmp_file.json>"
[[ -z $input ]] && { echo "$_help" ; exit 1; }
if [[ $input =~ ^http.*$ ]];then
url=$input
elif [[ -e $input ]]; then
tmp_file="$input"
else
echo "wtf is that: ${input}"
echo ${_help}
exit 1
fi
function _select(){
read -r -d '' _cmd_jq <<-'EOF'
{ jq '."{r}"' | jq '{url, title, channel, view_count, duration_string, id}'; }
EOF
read -r -d '' _jq_img <<-'EOF'
{ jq '."{r}"' | jq -r '.thumbnails.[-1].url' | xargs curl -Ls | chafa --view-size=${FZF_PREVIEW_COLUMNS}x${FZF_PREVIEW_LINES} }
EOF
local _preview="${_cmd_jq} <${tmp_file} | bat --language=json --color=always --style=plain; ${_jq_img} <${tmp_file}"
select_title=$(jq -r 'keys[]' "$tmp_file" | fzf --preview "${_preview}" )
(( $? )) && exit 1
select_url=$(jq -r ".\"${select_title}\".url" "$tmp_file")
mpv "$select_url" > /dev/null || {
echo "Error with: ${select_title}"
echo "mpv error when open: ${select_url}"
read -n1 -rp "Quit? [y\n]: " answer
[[ $answer = [Yy] ]] && exit 1
}
[[ $INFINITE ]] && exec "$0" "$tmp_file"
return 0
}
[[ -v tmp_file ]] && _select
playlist_title=$( yt-dlp --flat-playlist --playlist-items 1 --print "%(playlist_title)s" "$url" )
playlist_title=$(tr "[:upper:]" "[:lower:]" <<< ${playlist_title} | tr -s " " | tr "áéíóúñ" "aeioun" | tr -d -c '[:alnum:][:space:]' | tr " " "-" )
tmp_file="/tmp/${playlist_title}.json"
[[ ! -e $tmp_file ]] && yt-dlp -j --flat-playlist "$url" | jq -s . | jq 'INDEX(.title)' > "$tmp_file"
_select
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment