Download a full YouTube playlist with PowerShell

Recently, a colleague approached me requesting pointers on the quickest possible way to download a YouTube playlist.  I’d used KeepVid.com previously, to download videos one at a time, but never found a good tool to use to download a full playlist.  So I decided to make one!

Prerequisites

This tool depends on you already having the wonderfully useful youtube-dl.exe downloaded on your system.  I placed it in my %PATH% directory, but you can also run this code directly from wherever you placed the binary.  Get the tool here if you don’t already have it:  http://rg3.github.io/youtube-dl/


You should make sure your link loads in Playlist form.  It should look like this:

https://www.youtube.com/playlist?list=PL8B03F998924DA45B

 You can get your playlist by selecting the URL from a page that will generally look like this.
You can get your playlist by selecting the URL from a page that will generally look like this.

If it doesn’t contain a playlist, this method won’t work for you.  Once you have your URL, provide it in the $PlayListURL in the top line of the code:

 

$Playlisturl = "http://www.youtube.com/playlist?list=PL1058E06599CCF54D&"

Next, the real magic happens in this ungainly one-liner

$VideoUrls= (invoke-WebRequest -uri $Playlisturl).Links | ? {$_.HREF -like "/watch*"} | `
? innerText -notmatch ".[0-9]:[0-9]." | ? {$_.innerText.Length -gt 3} | Select innerText, `
@{Name="URL";Expression={'http://www.youtube.com' + $_.href}} | ? innerText -notlike "*Play all*"

We’ll break it down element by element:

We begin by Invoking a WebRequest for our URL and selecting all of the links. Next, we select only the playlist items that contain a direct video reference (contains “/watch”), then further filter to remove those without a playtime in the innerText field, which indicates direct links to times within videos.

Next, we remove items with a title with less than three characters, to remove duplicate entries, then we move on down the pipeline to set up a calculated property to perform some adjustment to the URL property.  We finally remove all items that survived to this point, which have ‘Play All’ in their name (which is typically reserved for the first entry in a playlist.

Sample output of a playlist
Sample output of a playlist

This gets saved and then fed to the binary one by one!

ForEach ($video in $VideoUrls){
Write-Host "Downloading $($video.innerText)"
.\youtube-dl.exe $video.URL
}

 

This process supports WGET, so your downloads can even resume!

Completed Code

$Playlisturl = "http://www.youtube.com/playlist?list=PL1058E06599CCF54D"
$VideoUrls= (invoke-WebRequest -uri $Playlisturl).Links | ? {$_.HREF -like "/watch*"} | `
? innerText -notmatch ".[0-9]:[0-9]." | ? {$_.innerText.Length -gt 3} | Select innerText, `
@{Name="URL";Expression={'http://www.youtube.com' + $_.href}} | ? innerText -notlike "*Play all*"

$VideoUrls

ForEach ($video in $VideoUrls){
Write-Host ("Downloading " + $video.innerText)
.\youtube-dl.exe $video.URL
}
Advertisements

7 thoughts on “Download a full YouTube playlist with PowerShell

  1. Jason Mallory July 8, 2014 / 8:33 pm

    At C:\Users\DEV\Documents\sys-scripts\powershell\playlistdownload.ps1:4 char:98
    + … ke “*Play all*”
    + ~
    The ‘<' operator is reserved for future use.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported

    • FoxDeploy July 8, 2014 / 8:48 pm

      I’m trying a new method of pasting code, and it looks like it messed something up, I’ll check it when I’m back at a keyboard. Thanks for the heads up!

    • FoxDeploy July 9, 2014 / 3:10 pm

      I flubbed the MarkDown syntax and had an extra ‘' tag in there, which PowerShell would interpret literally. Give it a go now :)

  2. danevald (@danevald) July 10, 2014 / 9:00 am

    If I see or copy from the above code-block I get all the ” as " and a few ‘ that’s not supposed to be there. Is this just me?

    • FoxDeploy July 10, 2014 / 4:20 pm

      Can you give new an example? This same script block worked for our purposes. There might be slightly different title formatting in your Playlist that I’ll need to allow for.

  3. takertx April 30, 2017 / 9:37 pm

    I also have a minimal issue with the script as it is as well. It goes through the videos in the playlist just fine and downloads them all just fine. The problem is that once it finishes with the last video in the playlist it starts over from the beginning of the list and gets stuck in a loop. It does not re download what it has already downloaded mind you, it just iterates over each entry and says that 100% of how ever megabytes the size of the file is has been downloaded and keeps going on an endless loop until stopped manually.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s