CLI utility to search and view/download YouTube videos

searchyoutubeyoutube-dl

Is there a utility that can search YouTube from the command line, and then either view or download the search results according to user input?

$ youtube-search madonna

1 Madonna - Hung Up (Official Music Video)
madonna ♩ 180M views 9 years ago

"Hung Up" by Madonna from Confessions On A Dance Floor, available now.

2 Madonna - Like A Prayer (Official Music Video)
madonna ♩ 69M views 9 years ago

2006 WMG Like A Prayer.

etc.

And then you can enter:

  • "v1" to view video 1 (with VLC, etc.)
  • "d1-3" to download videos 1-3 (with youtube-dl, etc.)
  • "n" to view next page of search results

What I tried so far:

googler works partially with YouTube, but for some reason only shows two search results when searching for "Madonna". Also there is not the choice between view and download.

youtube-dl has a search function, but doesn't seem to print the search results nor accept user input. youtube-dl -j ytsearch:madonna lists metadata about search results, but doesn't seem to contain the video link, title and description that would be desired.

Best Answer

Firstly, you need ytsearchN: to ask for N results. Secondly, make sure that you have the latest youtube-dl (I had some issues with an old version).

The following basic script will get 5 results, display their titles and urls, and ask which to download. Making it respond to the commands "vN" and "dN" would be simple ("dN" is effectively already implemented); I'm not sure how you could get the next page of results, though.

#!/bin/bash

tempfile=$(mktemp)
youtube_dl_log=$(mktemp)

youtube-dl -j "ytsearch5:$*" > $tempfile

# workaround for lack of mapfile in bash < 4
# https://stackoverflow.com/a/41475317/6598435
while IFS= read -r line
do
    youtube_urls+=("$line")
done < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )
# # for bash >= 4
# mapfile -t youtube_urls < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )

cat $tempfile | jq '.fulltitle, .webpage_url'

while :
do
    echo "Enter video number to download."
    read i
    # don't download anything if you just press enter
    if [ ! x"$i" == x"" ]
    then
        # to make numbering of videos more intuitive (start from 1 not 0)
        youtube-dl --no-progress ${youtube_urls[$i - 1]} &
    fi
done

You might, perhaps, want to redirect the output from youtube-dl to a file (or /dev/null), though it could also be considered useful.

Related Question