@ -2,10 +2,13 @@
# Requires:
# Requires:
# * curl
# * curl
# * fzf
# * fzf | rofi
# * jq
# * jq
# * hq
# * youtube-dl
# * youtube-dl
# * hq | pup (recomended, although optional)
rofi="auto"
ttyecho(){
ttyecho(){
# Same as echo but always to tty
# Same as echo but always to tty
echo "$@" > /dev/tty
echo "$@" > /dev/tty
@ -42,7 +45,21 @@ forceread(){
echo "$answer"
echo "$answer"
}
}
useRofi(){
[ "$rofi" = "yes" ] && return 0
local isxclient=$( readlink /dev/fd/2 | grep -q 'tty' && [[ -n $DISPLAY ]] ; echo $? )
if [[ ! -t 2 || $isxclient == "0" ]]; then
return 0
else
return 1
fi
}
getSearchTerm(){
getSearchTerm(){
if useRofi; then
# Rofi can't reload the suggestions so just display a search box
echo "" | rofi -dmenu -lines 0
else
# Uses fzf to get a search term
# Uses fzf to get a search term
# It will filter suggestions using youtube's autocomplete
# It will filter suggestions using youtube's autocomplete
export -f getSearchSuggestions
export -f getSearchSuggestions
@ -51,6 +68,7 @@ getSearchTerm(){
--header="Search Suggestions" \
--header="Search Suggestions" \
--phony \
--phony \
--height=50% --layout=reverse
--height=50% --layout=reverse
fi
}
}
getSearchSuggestions(){
getSearchSuggestions(){
@ -86,18 +104,35 @@ jq '..|.videoRenderer?' | sed '/^null$/d' |
}
}
chooseVideo(){
chooseVideo(){
if useRofi; then
( jq -r '[ .title, .channel, .views, .time, .age, .video ] | @tsv') |
column -t -s" " | sed $'s/ \([^ ]\)/\u00a0\\1/g' |
rofi -dmenu
else
(echo -e "Title\tChannel\tViews\tTime\tAge\tId"
(echo -e "Title\tChannel\tViews\tTime\tAge\tId"
jq -r '[ .title, .channel, .views, .time, .age, .video ] | @tsv') |
jq -r '[ .title, .channel, .views, .time, .age, .video ] | @tsv') |
column -t -s" " | sed $'s/ \([^ ]\)/\u00a0\\1/g' |
column -t -s" " | sed $'s/ \([^ ]\)/\u00a0\\1/g' |
fzf --header-lines="1" --with-nth=1,2,3,4,5 --delimiter=$'\u00a0'
fzf --header-lines="1" --with-nth=1,2,3,4,5 --delimiter=$'\u00a0'
fi
}
}
chooseQuality(){
chooseQuality(){
if [ -n "$1" ]; then
videoId="$1"
else
videoId="$(cat - | awk -F $'\u00a0' '{print $6}')"
videoId="$(cat - | awk -F $'\u00a0' '{print $6}')"
fi
if useRofi; then
code="$( (
echo "bb Best of Both"
youtube-dl "$videoId" -F | sed -n '/format code/,$ p' | sed 1d;
) | rofi -dmenu -prompt "Quality " -m | cut -d ' ' -f 1 )"
else
code="$( (
code="$( (
echo "bb Best of Both"
echo "bb Best of Both"
youtube-dl "$videoId" -F | sed -n '/format code/,$ p' | sed 1d;
youtube-dl "$videoId" -F | sed -n '/format code/,$ p' | sed 1d;
) | fzf --prompt "Quality " -m | cut -d ' ' -f 1 )"
) | fzf --prompt "Quality " -m | cut -d ' ' -f 1 )"
fi
code="$(echo "$code" | tr '\n' '+' | sed 's/+$//')"
code="$(echo "$code" | tr '\n' '+' | sed 's/+$//')"
@ -107,12 +142,46 @@ chooseQuality(){
esac
esac
}
}
main(){
main(){
local searchTerm="$*"
local url=""
local videoID=""
local searchTerm=""
while [[ "$1" = -?* ]]; do
case "$1" in
-u|--url)
if [ -n "$2" ]; then
url="$2"
shift
else
url="$(cat -)"
fi
shift
;;
--rofi)
rofi=yes
shift
;;
esac
done
if [ -n "$url" ]; then
case "$url" in
# If it contains an equals sign, let's assume it's a url
# Get the value of the v parameter
*=*) videoID="$(echo "$url" | grep -Eo '(\?|&)v=[^?&]*' | cut -d '=' -f 2)" ;;
# If there isn't an =, assume it is just the video ID
*) videoID="$url"
esac
chooseQuality "$videoID"
else
searchTerm="$*"
[ -z "$searchTerm" ] && searchTerm="$(getSearchTerm)"
[ -z "$searchTerm" ] && searchTerm="$(getSearchTerm)"
performSearch "$searchTerm" | extractVideoInfo | chooseVideo | chooseQuality
performSearch "$searchTerm" | extractVideoInfo | chooseVideo | chooseQuality
fi
}
}
main "$@"
main "$@"