youtube-dl-music (3092B)
1 #!/bin/sh 2 # requirements: youtube-dl, id3tag 3 4 set -e 5 6 musicroot="/home/music/" 7 8 die() { 9 printf '%s: error: %s\n' "${0##*/}" "$1" >&2 10 exit 1 11 } 12 13 show_help() { 14 printf 'usage: %s [OPTIONS] [URL ..]\n' "${0##*/}" 15 echo "downloads music from the web and tags it. Playlists are supported." 16 echo "If no URLs are supplied as arguments, they are expected as stdin." 17 echo 18 echo "OPTIONS are one or more of the following:" 19 echo " -a add metadata without interaction" 20 echo " -h show this message" 21 echo " -m move output music file to $musicroot" 22 echo " -q add to mpd queue (requires -m)" 23 echo " -t download through torsocks(1)" 24 echo " -- do not consider any following arguments as options" 25 } 26 27 ytdl() { 28 $prefix youtube-dl \ 29 --format bestaudio \ 30 --extract-audio \ 31 --audio-quality 0 \ 32 --audio-format mp3 \ 33 --add-metadata \ 34 --output "%(playlist_index)s - %(title)s.%(ext)s" \ 35 "$1" 36 } 37 38 handle_url() { 39 oldpwd="$PWD" 40 outputdir="$(mktemp -d)" 41 mkdir -p "$outputdir" 42 cd "$outputdir" 43 44 album="$(ytdl "$1" | tee /dev/tty | grep 'Finished downloading' | sed 's/.*: //')" 45 46 if [ $? -ne 0 ]; then 47 die "youtube-dl error" 48 fi 49 50 if [ "$(ls *.mp3 2>/dev/null | wc -l)" -lt 1 ]; then 51 printf "youtube-dl error" "$1" 52 if [ -n "$DISPLAY" ]; then 53 notify -u CRITICAL "youtube-dl error" "$1" 54 fi 55 exit 1 56 fi 57 58 if [ "$auto" = 0 ]; then 59 printf "add metadata? [Y/n] " 60 read 61 else 62 REPLY=y 63 fi 64 65 case "$REPLY" in 66 N|n) 67 mv ./*.mp3 "$oldpwd/" 68 cd - 69 exit 0;; 70 esac 71 72 artist="Unknown Artist" 73 album="${album:-Unknown Album}" 74 track=1 75 76 # Loop over files with spaces 77 SAVEIFS=$IFS 78 IFS=$(printf '\n\b') 79 for f in *.mp3; do 80 81 [ "$track" = 1 ] && \ 82 artist="$(printf '%s' "$f" | \ 83 awk -F'-' '{gsub(/^ +/, "", $2); gsub(/ +$/, "", $2); print $2}')" 84 85 printf 'file: %s\n' "$f" 86 87 song=$(printf '%s' "$f" | sed 's/.* - //; s/^ //; s/\.mp3//') 88 89 if [ "$auto" = 0 ]; then 90 printf 'song [%s]: ' "$song" 91 read 92 song="${REPLY:-$song}" 93 94 printf 'track [%s]: ' "$track" 95 read 96 track="${REPLY:-$track}" 97 98 printf 'album [%s]: ' "$album" 99 read 100 album="${REPLY:-$album}" 101 102 printf 'artist [%s]: ' "$artist" 103 read 104 artist="${REPLY:-$artist}" 105 fi 106 107 id3tag --artist="$artist" --album="$album" \ 108 --song="$song" --track="$track" \ 109 "$f" 110 111 track=$(( track + 1 )) 112 done 113 114 IFS=$SAVEIFS 115 116 if [ "$move_music" = 1 ]; then 117 outdir="$musicroot/$artist/$album" 118 mkdir -p "$outdir" 119 mv ./*.mp3 "$outdir" 120 if type -v mpc >/dev/null 2>&1; then 121 mpc update --wait >/dev/null 122 if [ "$queue" = 1 ]; then 123 mpc findadd \ 124 artist "$artist" \ 125 album "$album" \ 126 title "$song" 127 fi 128 fi 129 else 130 mv ./*.mp3 "$oldpwd/" 131 fi 132 133 rmdir "$outputdir" 134 cd - >/dev/null 135 } 136 137 prefix="" 138 auto=0 139 move_music=0 140 queue=0 141 while :; do 142 case "$1" in 143 -a) 144 auto=1;; 145 -h) 146 show_help 147 exit 0;; 148 -m) 149 move_music=1;; 150 -q) 151 queue=1;; 152 -t) 153 prefix="torsocks";; 154 --) 155 shift 156 break;; 157 -?*) 158 die "unknown option specified: $1";; 159 *) 160 break 161 esac 162 shift 163 done 164 165 if [ $# -lt 1 ]; then 166 urls="$(cat)" 167 else 168 urls="$@" 169 fi 170 171 for u in "$urls"; do 172 handle_url "$u" 173 done