dotfiles

configuration files for shell, text editor, graphical environment, etc.
git clone git://src.adamsgaard.dk/dotfiles # fast
git clone https://src.adamsgaard.dk/dotfiles.git # slow
Log | Files | Refs | README | LICENSE Back to index

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