Watch youtube videos without a browser, suckless style
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.8 KiB

#!/bin/bash
RESULTS=10
CHANNEL_SEARCH=false
THUMBNAILS=true
MPV_DIRECT=false
function usage() {
cat <<USAGE
Usage: $0 [-n --number-results] [-c --channel-search]
Options:
-n, --number-results: the number of results to include
-c, --channel-search: search for the first n results of the first channel matching the query
-m, --mpv-direct: use mpv's built-in youtube-dl function to render video instead of a pipe (more info, but worse buffering)
--disable-images: don't bother downloading thumbnails (because your dmenu isn't patched)
USAGE
exit 1
}
while [ "$1" != "" ]; do
case $1 in
-n | --number-results)
shift
RESULTS=$1
;;
-c | --channel-search)
shift
CHANNEL_SEARCH=true
;;
--disable-images)
shift
THUMBNAILS=false
;;
-m | --mpv-direct-stream)
shift
MPV_DIRECT=true
;;
-h | --help)
usage # run usage function
;;
*)
usage
exit 1
;;
esac
shift # remove the current value for `$1` and use the next
done
start_tabbed () {
YTE=$(xdotool search --classname "SucklessYT" | tail -n1)
if [[ "$YTE" = *[![:space:]]* ]]
then
XID="$YTE"
else
FIFO="$(mktemp -u)"
mkfifo "$FIFO"
tabbed -n "SucklessYT" > "$FIFO" &
jobs # Get rid of the "Completed" entries
TABBEDPID="$(jobs -p %%)"
if [ -z "$TABBEDPID" ] ; then
echo "Can't start tabbed"
exit 1
fi
read -r XID < "$FIFO"
rm "$FIFO"
fi
}
start_tabbed
search_query=$(echo "" |
dmenu -c -w "$XID" -p "Search")
if [[ $CHANNEL_SEARCH == false ]]; then
search_data=$(caoydl -s "$search_query" | head -n "$RESULTS")
else
# note: the second call to caoydl is very slow -- can probably be spead up by reading / parsing the rss feed
search_data=$(caoydl -c "$search_query" | head -n 1 | awk -F"\t" '{print $1}' | xargs -I{} curl -s "https://www.youtube.com/feeds/videos.xml?channel_id={}" | xmltojson | jq -r '.feed.entry[] | "\(.id)\t\(.title)"' | sed -e 's/yt:video://g' | head -n "$RESULTS")
fi
## Write the thumbnails to a temporary directory and go into that directory
if [[ $THUMBNAILS == true ]]; then
IMAGES="$(mktemp -d)"
cd "$IMAGES" || exit
echo "$search_data" | awk -F"\t" '{print $1}' | xargs -P "$RESULTS" -I{} wget -O '{}.jpg' 'https://i1.ytimg.com/vi/{}/hqdefault.jpg'
find . -print 0 | xargs -0 -P "$RESULTS" -I{} convert {} -scale 100x133 {}
fi
if [[ $THUMBNAILS == true ]]; then
## Use special patched dmenu that can render images like @image.jpg (similar to suckless Sent)
RESULT=$(echo "$search_data" | sed 's/^/\@/' | sed 's/\t/.jpg\t/' | dmenu_images -c -l "$RESULTS" -i -w "$XID")
TITLE=$(echo "$RESULT" | awk -F"\t" '{print $2}')
yt_id=$(echo "$RESULT" | awk -F"\t" '{print $1}' | sed 's/\@//' | sed 's/.jpg//')
else
TITLE=$(echo "$search_data" | awk -F"\t" '{print $2}' | dmenu -c -l "$RESULTS" -i -w "$XID")
yt_id=$(echo "$search_data" | grep "$TITLE" | awk -F"\t" '{print $1}')
fi
if [[ $MPV_DIRECT == false ]]; then
yt-dlp -N 100 -f 22 "$yt_id" -o - | mpv - --keep-open=yes --force-window=immediate --wid="$XID" &
MPV_PID=$!
else
## Using MPV directly to render the video has the advantage that it will pull chapters
## But it seems to not obey the concurrent download setting which can lead to occasional stuttering if
## the video doesn't buffer enough
mpv "https://youtube.com/watch?v=$yt_id" \
--ytdl-format="22" \
--keep-open=yes \
--force-window=immediate \
--wid="$XID" &
MPV_PID=$!
fi
## Wait for the MPV window to spawn and set the title of the tab to the video title
while [[ $(xdotool search --pid "$MPV_PID" | wc -l) -eq 0 ]]; do
sleep 1
done
MPV_WID=$(xdotool search --pid "$MPV_PID")
xprop -id "$MPV_WID" -set WM_NAME "$TITLE"