Last active
April 18, 2020 18:26
-
-
Save tildelowengrimm/e3e5d2b6e0765155db0647d77895e984 to your computer and use it in GitHub Desktop.
Archive Synthwave Mixes from Astral Throb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Download the excellent synthwave mixes created by Astral Throb, split the | |
## audio into individual songs, and label them with metadata, including | |
## excellent cover art. Ideal for offline listening. | |
## Dependencies: | |
## - youtube-dl | |
## - jq | |
## - ffmpeg | |
## - eyeD3 | |
## TODO | |
## 1. Catch errors where YouTube-DL fails to grab the initial playlist. | |
## 2. Don't allow the infofile, album, title, &c to be blank when parsing — | |
## treat as an error and skip that album while downloading. | |
## 3. If there have been errors, don't try to move the final file. | |
ALBUM_ARTIST="Astral Throb" | |
GENRE="Electronic" | |
ARTIST_HOMEPAGE="https://www.youtube.com/channel/UCpbH_7H71IPKq4eH7CD5spg" | |
PLAYLIST_URL="https://www.youtube.com/playlist?list=UUpbH_7H71IPKq4eH7CD5spg" | |
TARGET_DIR="$HOME/media/music/library/$ALBUM_ARTIST" | |
ARTIST_LOGO="$TARGET_DIR/astral-throb.jpg" # This file is not created, it should already exist in the target directory | |
## Colors for output | |
RED='\033[0;31m' | |
LIGHT_PURPLE='\033[1;35m' | |
NC='\033[0m' # No Color | |
echo "Archiving $ALBUM_ARTIST to ${LIGHT_PURPLE}$TARGET_DIR${NC}." | |
## Download and parse the list of URLs in the playlist | |
echo "Fetching work queue…" | |
PLAYLIST_LIST=$(youtube-dl --dump-json --flat-playlist "$PLAYLIST_URL" | jq -r '.id' | sed 's_^_https://youtube.com/v/_') | |
#PLAYLIST_LIST="https://www.youtube.com/watch?v=isIj3tuQTDY&t=2015s" # For testing with individual albums which encounter errors | |
for URL in $PLAYLIST_LIST | |
do | |
## Skip SIMULAKRUM LAB, which isn't actually a mix | |
[[ "$URL" == "https://youtube.com/v/6DaQbh45OxI" ]] && echo "Skipping SIMULAKRUM LAB…" && continue | |
## Download the metadata file for the album | |
INFOFILE=$(youtube-dl --skip-download --write-info-json "$URL" | grep "Writing video description metadata as JSON to" | cut -c 55- ) #; echo "INFOFILE: $INFOFILE" | |
[[ "$INFOFILE" == "" ]] && echo "Metadata download failed, skipping…" && continue | |
PREFIX=$(echo "$INFOFILE" | rev | cut -c 11- | rev) | |
## Parse basic album metadata from the file | |
ALBUM_TITLE=$(cat "$INFOFILE" | jq .fulltitle | cut -d ' ' -f 1 | cut -c 2-) #; echo "ALBUM_TITLE: $ALBUM_TITLE" # The short all-caps title | |
ALBUM_YEAR=$(cat "$INFOFILE" | jq ".upload_date" | cut -c 2-5) #; echo "ALBUM_YEAR: $ALBUM_YEAR" # Four-digit album year | |
ALBUM_DIRECTORY="$ALBUM_ARTIST - $ALBUM_TITLE ($ALBUM_YEAR)" #; echo "ALBUM_DIRECTORY: $ALBUM_DIRECTORY" | |
## Check to see if this album already existst in the target directory, otherwise create it here | |
if [ -d "$TARGET_DIR/$ALBUM_DIRECTORY" ] | |
then | |
rm "$INFOFILE" | |
echo "$ALBUM_TITLE has already been downloaded." | |
rm "$PREFIX"* | |
continue | |
else | |
mkdir "$ALBUM_DIRECTORY" | |
fi | |
ALBUM_FULLTITLE=$(cat "$INFOFILE" | jq --raw-output .fulltitle) | |
echo "Processing $ALBUM_FULLTITLE …" | |
## Download the audio and the thumbnail from YouTube | |
echo " Downloading $ALBUM_TITLE combined mix & art…" | |
ALBUM_AUDIO=$(youtube-dl --format bestaudio --extract-audio --write-thumbnail "$URL" | grep Destination | grep ffmpeg | cut -c 23-) | |
## Parse the remaining album metadata | |
RELEASE_DATE=$(cat "$INFOFILE" | jq ".upload_date" | cut -c 2-5)-$(cat "$INFOFILE" | jq ".upload_date" | cut -c 6-7)-$(cat "$INFOFILE" | jq ".upload_date" | cut -c 8-9) | |
TRACKS=$(cat "$INFOFILE" | jq ".chapters | length") | |
## Move the album art | |
echo " Exporting $ALBUM_TITLE cover art…" | |
ALBUM_ART="$ALBUM_DIRECTORY/$ALBUM_FULLTITLE.jpg" | |
mv "$PREFIX.jpg" "$ALBUM_ART" | |
## Extract the individual audio files from the combined album mix | |
for INDEX in $(seq 1 $TRACKS) | |
do | |
## Parse this audio track's metadata | |
TRACK_ARTIST="$(cat "$INFOFILE" | jq --raw-output ".chapters["$[$INDEX-1]"].title" | cut -d - -f 1 | rev | cut -c 2- | rev | sed 's/^\///;s/\// /g' )" | |
TRACK_TITLE="$(cat "$INFOFILE" | jq --raw-output ".chapters["$[$INDEX-1]"].title" | cut -d - -f 2 | cut -c 2- | sed 's/^\///;s/\// /g' )" | |
TRACK_START="$(cat "$INFOFILE" | jq ".chapters["$[$INDEX-1]"].start_time")" | |
TRACK_END="$(cat "$INFOFILE" | jq ".chapters["$[$INDEX-1]"].end_time")" | |
## Single-digit track numbers are zero-prefixed in the filename | |
if (( $INDEX < 10 )) ; then | |
FILENAME="$ALBUM_DIRECTORY/0$INDEX. $TRACK_ARTIST - $TRACK_TITLE.mp3" | |
else | |
FILENAME="$ALBUM_DIRECTORY/$INDEX. $TRACK_ARTIST - $TRACK_TITLE.mp3" | |
fi | |
## The heavy lifting of audio extraction for this track | |
echo " Extracting $ALBUM_TITLE track $INDEX/$TRACKS $TRACK_ARTIST - $TRACK_TITLE …" | |
ffmpeg -loglevel warning -y -i "$ALBUM_AUDIO" -ss "$TRACK_START" -to "$TRACK_END" "$FILENAME" && echo " Track extraction successful." || echo " ${RED}Track extraction failed!${NC}" | |
## Write the metadata to the file | |
echo " Writing tack metadata for $TRACK_ARTIST - $TRACK_TITLE …" | |
eyeD3 \ | |
--artist "$TRACK_ARTIST" \ | |
--album "$ALBUM_FULLTITLE" \ | |
--album-artist "$ALBUM_ARTIST" \ | |
--title "$TRACK_TITLE" \ | |
--release-year "$ALBUM_YEAR" \ | |
--track "$INDEX" \ | |
--track-total "$TRACKS" \ | |
--genre "$GENRE" \ | |
--release-date "$RELEASE_DATE" \ | |
--url-frame "WOAS:$URL" \ | |
--url-frame "WOAR:$ARTIST_HOMEPAGE" \ | |
--add-image "$ARTIST_LOGO:BAND_LOGO" \ | |
--add-image "$ALBUM_ART:FRONT_COVER" \ | |
"$FILENAME" >/dev/null | |
done | |
## Move the complete albim to the target directory | |
echo " Extraction complete. Moving $ALBUM_TITLE to library…" | |
rsync --recursive --remove-source-files --compress "$ALBUM_DIRECTORY" "$TARGET_DIR" | |
## Remove the original audio, thumbnail, and metadata file | |
echo " $ALBUM_TITLE archived, cleaning up…" | |
rm "$PREFIX"* | |
rm -r "$ALBUM_DIRECTORY" | |
done | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment