ulthar.xyz > Repos

dotfiles

Seven years worth of accumulated configuration cruft
About Files Commits git clone https://ulthar.xyz/repos/dotfiles/dotfiles.git

dotfiles/scripts/.local/bin/ytmu

Download raw file: scripts/.local/bin/ytmu

#!/bin/sh
# Download music from YouTube and embed extra metadata fetched from
# genius.com.
# Dependencies: yt-dlp, opuscomment, lyrics (in this repo)

set -e

[ -z "$1" ] && {
	echo "Download audio with youtube-dl.  Usage: ytmu [urls...]" >&2
	exit 1
}

too_long_for_opuscomment() { test "$(wc -c "$1" | cut -d' ' -f1)" -ge 131066; return $?; }

cleanup() { rm -fv ytmu_*_tmp.???.txt; }

fetch_audio() {
	url="$1"
	yt_dlp_outfile="$2"
	output="%(track,title)s.%(ext)s"
	# If we're downloading all playlists from a youtube channel,
	# stick them in a dedicated directory
	[ ! "$url" = "${url%%/playlists}" ] && output="%(playlist)s/$output"
	yt-dlp \
		--extract-audio \
		--audio-format opus \
		--audio-quality 0\
		--add-metadata \
		--embed-thumbnail \
		--sponsorblock-mark all \
		--output "$output" \
		--exec "echo {} >>$yt_dlp_outfile" \
		$YTMU_YTDLP_EXTRA_OPTS \
		"$url"
}

fetch_lyrics() {
	lyrics_outfile="$1"
	yt_dlp_outfile="$2"
	while read -r line; do
		file="$(basename "$line")"
		term="${file%%.opus}"
		echo "Fetching lyrics for $term..."
		if lyrics "$term" > "$lyrics_outfile"; then
			if too_long_for_opuscomment "$lyrics_outfile"; then
				echo "Lyrics file too long for opuscomment" >&2
			else
				echo "Adding lyrics to $file..."
				opuscomment \
					-t "lyrics=$(cat "$lyrics_outfile")" \
					-a "$file"
			fi
		fi
	done < "$yt_dlp_outfile"
}

trap cleanup INT HUP QUIT ABRT

for url in "$@"; do
	yt_dlp_outfile="$(mktemp ytmu_yt_dlp_tmp.XXX.txt)"
	lyrics_outfile="$(mktemp ytmu_lyrics_tmp.XXX.txt)"
	fetch_audio "$url" "$yt_dlp_outfile"
	fetch_lyrics "$lyrics_outfile" "$yt_dlp_outfile"
	cleanup
done
Generated 2025-08-15 22:34:15 +0000 by RepoRat