[Bash Script] Download YouTube content ready for Plex.

This script will scrawl a Youtube playlist, or channel and download all the recent videos from said channel.

Requirements:
Linux Server: May work on Windows, or Mac, no idea though. Never tried bash scripting on either platform and very new to it on Linux.
youtube-dl: rg3.github.io/youtube-dl/
Plex Extended Media Scanner: forums.plex.tv/discussion/88982/rel-extended-personal-media-scanner
Plex Extended Media Agent: forums.plex.tv/discussion/83440/rel-extended-personal-media-shows-agent/
rename: Was included with my Ubuntu 14.04 distribution and I know it’s also included with Debian Jessy, but not sure on others.

I generally call my script SeriesBlank and then just edit and rename when I want to add another playlist to be managed.

Everything in the <BRAKETS> needs to be edited, and you’ll need to make sure it’s set to the correct directory’s for your files.

YOUTUBEOUT: should be where you want the files to end up, now this is totally up to you because I had troubles with the scanners not picking up the files when I downloaded them directly into the directory Plex watched. So I just manually move them when I’ve noticed a few have downloaded to the folders. This also formats the show folder as well as the beginning of the Series Name, to comply with the Extended Media Scanners naming conventions

PLAYLIST: This is just the URL from the playlist.

CDDIR: I had to rename the files after the download has completed, and my bash scripting knowledge is limited so I just made it CD back into the directory to complete the naming tasks, this should be the same as YOUTUBEOUT up until the season folder.

ARCHIVEFILE: This is the file that tracks what episodes have been downloaded, I use this because of renaming the files after download. Youtube-dl doesn’t allow many naming options.

MATCHTITLE: This is optional, and I only really use it if the youtube channel I’m watching doesn’t use the playlists feature. Just add {MATCHTITLE} inbewtween {ARCHIVEFILE} and –ignore errors.

The last bit to really pay attention to is the naming of the videos on youtube. Plex Extended Scanners require “Show Name – YYYY-MM-DD – Epsidoe Title.ext”. With the way the names are pulled from youtube there can be over hang, and I have ended up duplicating the show name like “Show Name – YYYY-MM-DD – Show Name – Episode Title.ext” which blagges the extended scanner something rotten. So on my Rename comment I’ve added- <REMOVE FROM TITLE>.This is literally just to remove that part of the name, if it isn’t there on the youtube titles then you don’t need to remove anything. I have posted a working example from a channel I keep up to date with, so you can see how it works.

It may be easier to name your shows with S01E01, and it’s certainly possible with this script, but I found it was very hit and miss with OnDeck as that uses dates for organisation. With limited meta data as well, this seamed the easiest way to hit both of those requirements.

Please feel free to ask questions, and if anyones more versed in bash than me, feel free to upgrade the script. My guess is there should be a way to automate most of what I’ve done, I’m just low on time at the min and brain power for picking up Bash more.

If your also wondering why I’m downloading the .description files and renaming them to .summary, it’s because it was the easiest option to get partial metadata from youtube, at least for the episode descriptions. For the album art, if you go into the Server Settings -> Agents -> Plex Extended Media Scanner, and tick the option to use local media, it will pick up any show-1.png or background-1.png.

I currently haven’t found a way to include the show description so I’ve just been inputting that manually.

#!/bin/bash

##Please fill in relevant information below. 

YOUTUBEOUT="/path to media/TV/Youtube Series/<SERIESNAME>/<SERIESNAME> -"
PLAYLIST="<PLAYLISTURL>"
CDDIR="/path to media/TV/Youtube Series/<FOLDERNAME^>"
ARCHIVEFILE="/path to media/Youtube/Logs/<SERIESTEXTFILE>.txt"
MATCHTITLE="--match-title "<TEXTTOREMATCH>""


##Download new videos
youtube-dl -o "${YOUTUBEOUT} %(upload_date)s - %(title)s.%(ext)s" --write-description --download-archive ${ARCHIVEFILE} --ignore-errors ${PLAYLIST} 


##CD to correct directory##
cd "${CDDIR}"

## Rename all *.description to *.summary
rename 's/\.description$/\.summary/' *.description

## Rename the YYYYMMDD to YYYY-MM-DD files... 
rename -v 's/(\d{4})(\d{2})(\d{2}) - <REMOVE FROM TITLE>/$1-$2-$3/' *

Working Example:

##!/bin/bash

##Please fill in relevant information below. 
YOUTUBEOUT="/media location/KA Physics/KA Physics -"
PLAYLIST="Had to delete URL dude to the forum displaying it as a video... it's just Khan academy's physics section"
CDDIR="/media location/KA Physics"
ARCHIVEFILE="/media location/Youtube/Logs/KA.Pysics.txt"

##Download new videos
youtube-dl -o "${YOUTUBEOUT} %(upload_date)s - %(title)s.%(ext)s" --write-description --download-archive ${ARCHIVEFILE} --ignore-errors ${PLAYLIST} 

##CD to correct directory##
cd "${CDDIR}"

## Rename all *.description to *.summary
rename 's/\.description$/\.summary/' *.description

## Rename the YYYYMMDD to YYYY-MM-DD files... 
rename -v 's/(\d{4})(\d{2})(\d{2})/$1-$2-$3/' *

This just had the title names on the episodes and no Show Name so there was no need to remove any additional text with the rename command.

To get description (embedded in downloaded file):

–add-metadata

That way included it in the mp4, which I had troubles getting the scanner to pick it up. Not sure if that’s still the case, if not either or will work fine.

This, as you you say, is pretty simple but it works pretty well. Thanks for posting it i’m using it now to download daily podcasts.

A suggested improvement would be to check if a new release is available and then download it or not. At the moment, it will just download the entire playlist over and over.

I’d like to run this in cron once a day to pick up a new release when it comes. I’m not sure how this could be achieved yet but am open to ideas if anyone wants to collaborate.

edited to add : I found this in the google api - http://gdata.youtube.com/feeds/api/users/CHANNELNAME/uploads?orderby=updated

It should list uploads sorted by date.

I created a little shell script to auto-download shows from my list that have aired since “yesterday”
showList.txt is just a flat file with certain subscriptions in it

  1. It looks and sees if the directories exist. If not, it creates them
  2. Creates a new directory based on the show name. If it already exists, it skips
  3. For every channel in the showList.txt, it searches that channel and auto-downloads the videos

oh, it runs on Ubuntu, no clue on how to implement a shell script in Windows.

Here is the contents of my file:

#!/bin/bash
DTE=date --date yesterday +%Y%m%d
SAVEPATH=/path/to/where/you/want/to/save/files//
DBPATH=/path/to/databases/YouYubeDl/
SHOWSLIST=/path/to/showlist/showList.txt

if ! [ -d “$SAVEPATH” ];
then
mkdir -p $SAVEPATH
echo “created $SAVEPATH”
fi

if ! [ -d “$DBPATH” ];
then
mkdir -p $DBPATH
echo “created $DBPATH”
fi

for SHOW in cat $SHOWSLIST; do

if ! [ -d “$SAVEPATH/$SHOW/” ];
then
mkdir -p $SAVEPATH/$SHOW
echo “created $SHOW”
fi
done

for SHOW in cat $SHOWSLIST; do
cd $SAVEPATH/$SHOW/
youtube-dl ytuser:$SHOW --dateafter $DTE --download-archive $DBPATH/$SHOW.txt
done

anyone using it on windows? and how do you set it up then? how do you use it? i am entirely new to this