Skip to content

Instantly share code, notes, and snippets.

@jkpl
Created October 22, 2011 19:58
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jkpl/1306420 to your computer and use it in GitHub Desktop.
Save jkpl/1306420 to your computer and use it in GitHub Desktop.
Script that downloads Youtube playlist and extracts the audio from the downloaded clips.
#!/bin/bash
## URL
# The URL to the Youtube playlist
URL="http://www.youtube.com/playlist?list=PL60BA016CD6B147F8"
## DESTPATH
# The path where to to download the music to
DESTPATH="$HOME/Music/awesome_new_music"
## TEMPDIR
# Directory for temporary videofiles
TEMPDIR="$DESTPATH/temp"
## CLEANUP
# Set to != 0 to remove temporary video files. If you don't clean the temp dir,
# ffmpeg will still extract audio from previously downloaded files.
CLEANUP=1
## PLAYLIST
# Filename for the local music playlist
PLAYLIST="playlist"
## UTIDLOG
# ID log for downloaded music files
UTIDLOG="downloaded.txt"
## TEMPLOG
# Temporary ID log for Youtube playlist
TEMPLOG="utplaylist.txt"
FFMPEG="/usr/bin/ffmpeg" # Path to ffmpeg
YOUTUBEDL="/usr/bin/youtube-dl" # Path to youtube-dl
#########
set -e
IFS="`printf '\n\t'`"
echo "YouTube playlist downloader"
echo "---------------------------"
# Check parameters
if [ "$1" == "help" ]; then
cat <<EOF
This script downloads videos from a Youtube playlist and
converts them to audio. It keeps track of what tracks have
already been downloaded before.
usage: `basename $0` [URL] [destpath]
usage: `basename $0` help
URL : playlist url
destpath : the destination path where to download the playlist
help : prints this help
EOF
exit 0
fi
[[ $# -gt 0 ]] && URL="$1"
[[ $# -gt 1 ]] && DESTPATH="$2"
# Create directories and files
if [ ! -d "$DESTPATH" ]; then
mkdir -p "$DESTPATH"
fi
if [ ! -d "$TEMPDIR" ]; then
mkdir -p "$TEMPDIR"
fi
for I in "$PLAYLIST" "$UTIDLOG" "$TEMPLOG"; do
if [ ! -f "$DESTPATH/$I" ]; then
touch "$DESTPATH/$I"
fi
done
cat <<EOF
Playlist: $URL
Destination: $DESTPATH
EOF
echo "Fetching playlist IDs... (this might take a while)"
# Indeed this is very slow. It'd be better to fetch the playlist info from
# YouTube API and parse the IDs from there. I'll fix this someday...
$YOUTUBEDL -s --get-filename "$URL" | cut -d"." -f 1 > "$DESTPATH/$TEMPLOG"
echo "Downloading videos..."
while read utid; do
if ! grep "^$utid" "$DESTPATH/$UTIDLOG" > /dev/null; then
$YOUTUBEDL -c -o "$TEMPDIR/%(stitle)s.%(ext)s" "$utid"
fi
done < "$DESTPATH/$TEMPLOG"
echo "Extracting the audio..."
for f in "$TEMPDIR/"*; do
if [ -e "$f" ]; then
# FFMpeg pretty much just extracts the audio track to a separate file.
# In some cases, it might be more wise to extract AND encode the audio.
fformat=$($FFMPEG -i "$f" 2>&1 | sed -n "s/\s*Stream .*: Audio: \([a-zA-Z0-9]\+\),.*/\1/p")
inname=`basename $f`
outname="${inname%.*}.$fformat"
#outname="${inname%.*}" # Alternative output filename
$FFMPEG -y -i "$f" -acodec copy "$DESTPATH/$outname"
#$FFMPEG -y -i "$f" -ab 192k "$DESTPATH/$outname.mp3" # Alternative way to extract audio
fi
done
# YouTube playlist -> downloaded
if [ -s "$DESTPATH/$TEMPLOG" ]; then
mv "$DESTPATH/$TEMPLOG" "$DESTPATH/$UTIDLOG"
else
rm -f "$DESTPATH/$TEMPLOG"
fi
# Create playlist
# Listed enough formats just to be sure.
find "$DESTPATH" -type f \( \
-iname "*.mp3" -o \
-iname "*.ogg" -o \
-iname "*.aac" -o \
-iname "*.flac" \) \
-printf "%f\n" > "$DESTPATH/$PLAYLIST"
if [ ! $CLEANUP -eq 0 ]; then
echo "Cleaning up temporary files..."
for f in "$TEMPDIR/"*; do
if [ -e "$f" ]; then
rm -fv "$f"
fi
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment