Slay Tube

Slay Tube is a bash wrapper for youtube-dl. Get a series of youtube videos by keyword. It will default to a single audio track. Specify: exclude vevo (from initial search only), n number to download, audio / video, subdirectory, and playlist search.

You'll only need to modify the path variable to reflect your download directory of choice.

I recognize that youtube-dl can grab an entire playlist already - I didn't realize this until halfway. I should really change it although, it's no more fragile than the rest of the script. I like it enough that I will likely update the script when (not if) it breaks

Example Usage:

slay-tube -w "the eels" -n 10 -f audio -l eels -p

Will make a subdirectory eels and download 10 Eels songs from the first playlist it finds (specifying audio was redundant).

To get a whole playlist just specify a big number like 1000, getNext() will return the youtube homepage when the playlist is done and will not attempt to download. No it's not pretty, but it won't really sap up resources either.

Download: slay-tube

    
  #!/bin/bash
  # get audio from youtube's 'Up next' links
  # Depends: cURL, grep, youtube-dl, ffmpeg, tr
  # Original: Mr_asdf
  # Modified: slim

  getVidFromKW() {
    kw=$(echo "$1" | tr " " +)
    if [ $playlist -eq 1 ]
      then
      kw+="&filters=playlist&lclk=playlist"
      dump=$(curl -s "https://www.youtube.com/results?search_query=/'$kw'")
      url="$(echo 'https://www.youtube.com/'$(echo "$dump" | grep -oE "<a href=\"/watch\?[^\"]+" | head -n 1 | grep -oE "watch\?[^\"]+"))"
      url=${url//"&amp;"/"&"}
      echo $url
    fi
    if [ $playlist -eq 0 ]
      then
      dump=$(curl -s "https://www.youtube.com/results?search_query=/'$kw'")
      echo 'https://www.youtube.com/'$(echo "$dump" | grep '<h3 class="yt-lockup-title "><a href=' | head -n 1 | grep -oE "watch\?[^\"]+")
    fi
  }

  getNext() {
    if [ ! $playlist -eq 1 ]
      then
      echo 'https://www.youtube.com/'$(curl -s "$1" | grep "Up next" -A 8 | tail -n 1 | grep -oE "watch\?[^\"]+")
    elif [ $playlist -eq 1 ]
      then
      playlistIndex="$2"
      let playlistIndex+=1
      url=$(echo "https://www.youtube.com/"$(curl -s "$1" | grep -oE "watch\?[^\]+index=${playlistIndex}" | head -n 1))
      url=${url//"&amp;"/"&"}
      echo $url
    fi
  }

  # initialize options
  path="/home/slim/Music/youtube"
  download_location=$path
  kw=""
  playlist=0
  format=audio
  num_songs=1
  x=1 # 1 default search, 0 exclude vevo
  h=0

  HELP() {
    echo "slay-tube uses youtube-dl to search to download audio/video"
    echo "additionally download from the 'up next' section or playlist"
    echo ""
    echo "Usage:"
    echo "slay-tube -w <\"my keywords\"> - required - don't forget the quotations!"
    echo ""
    echo "-x - exclude vevo from results"
    echo "-n <num to dl from next playing> - default 1"
    echo "-f <audio || video> - default audio"
    echo "-l <file path> (within default directory)"
    echo "-p - will only search playlists"
    echo "-h - this help screen"
    exit 0
  }

  while getopts :w:xn:f:l:ph FLAG; do
    case $FLAG in
    w) # keyword
      kw=$OPTARG
      ;;
    x)  #exclude vevo
      x=0
      echo "excluding vevo results from search"
      ;;
    n) # set num to get
        num_songs=$OPTARG
      ;;
    f) # set format
        format=$OPTARG
        if [ "$format" != "audio" ] && [ "$format" != "video" ]
          then
          echo "invalid format selection"
          HELP
          exit 1
        fi
      ;;
      l) # set location
        download_location="${path}/${OPTARG}"
        if [ ! -d "${download_location}" ]; then
          echo "creating download dir: $download_location"
          mkdir "${download_location}"
        fi
      ;;
      p) # playlist
        playlist=1
        ;;
      h)  #show help
        HELP
        ;;
      \?) #unrecognized option - show help
        echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed."
        HELP
        #If you just want to display a simple error message instead of the full
        #help, remove the 2 lines above and uncomment the 2 lines below.
        #echo -e "Use ${BOLD}$SCRIPT -h${NORM} to see the help documentation."\\n
        #exit 2
        ;;
    esac
  done

  shift $((OPTIND-1))

  # is kw set?
  if [ -z "$kw" ]
    then
    echo "no keyword given"
    HELP
    exit 1
  fi

  url_file="$(mktemp)"
  echo "Getting urls"
  next="$(getVidFromKW "$kw")"
  firstUrl="$next" # for playlist dl

  for i in `seq 1 $num_songs`;
  do
      if [ ! "$next" = "https://www.youtube.com/" ] # this means that finding the next url failed and defaulted to homepage
        then                                        # don't continue since they probably specified more vids than are available
        echo "$next" >> $url_file
        echo -n "."
        if [ $playlist -eq 1 ]
          then
          next="$(getNext "$firstUrl" "$i")"
        fi
        if [ $playlist -eq 0 ]
          then
          next="$(getNext "$next" "$i")"
        fi
      fi
  done

  echo "Getting music from urls to $download_location"

  if [ "$format" = "audio" ]
    then
    youtube-dl --no-playlist -i -x -o $download_location'/%(title)s.%(ext)s' -a "$url_file"
  elif [ "$format" = "video" ]
    then
    youtube-dl --no-playlist -i -o $download_location'/%(title)s.%(ext)s' -a "$url_file"
  fi