I wanted to download some YouTube videos to re-host for myself on Plex so that I could use the downloads feature to watch them offline, using the yt-dlp tool (a fork of the original yt-dl tool with additional features). Another advantage of this is that it eliminates ads. One issue though is that you lose some of the discovery and organization features on YouTube. In order to try to keep the videos organized, I wanted to preserve playlist info and video metadata. Here’s the script I used to do this. Note that ffmpeg also needs to be in the same folder, or added to the system path.
.\yt-dlp.exe "https://www.youtube.com/@channel/playlists" -S res:1080,ext:mp4:m4a -o "D:\Plex\YouTube\%(uploader)s\%(playlist_title)s\%(playlist_index)s %(title)s [%(id)s].%(ext)s" --add-metadata --compat-options embed-metadata --download-archive "D:\archive.txt" --match-filter "!is_live"
Here’s a quick breakdown of what it’s doing:
.\yt-dlp.exe “https://www.youtube.com/@channel/playlists” | Run yt-dlp in a Powershell terminal and provide the URL of the playlists page for the channel you want to download. |
-S res:1080,ext:mp4:m4a | Specify the resolution and format to download.
There’s a ton of potential options here. “-S best” will get the max quality video, though in my case I wanted to limit file size. For some downloads I use 720 as the resolution. |
-o “D:\Plex\YouTube\%(uploader)s\%(playlist_title)s\%(playlist_index)s %(title)s [%(id)s].%(ext)s” | Specify both the output path and file name format.
In my case I’m outputting to a network drive in a Plex library named “YouTube.” I’m then creating a folder for each channel and a sub-folder for each playlist. The %(title)s [%(id)s].%(ext)s file name format is close to the default, but I’m prefixing it with the %(playlist_index)s to make sorting easy. This may not be necessary depending on the video name or type of playlist. |
–add-metadata –compat-options embed-metadata | Embeds YouTube video metadata in the video. The compatibility options make it follow the default for the classic yt-dl program rather than yt-dlp. |
–download-archive “D:\archive.txt” | Logs the ID of each video downloaded to a text file to avoid repeats. |
–match-filter “!is_live” | Skips any videos in the playlist that are live streams.
Several of the channels I wanted to download had live streams that were just regurgitating other videos in the playlist in a livestream format. I didn’t need to download these, but since they were part of the playlist, yt-dlp would start capturing the stream and it would block the rest of the downloads. This avoided that problem. |
Once I downloaded all the playlists, I wanted to capture anything that wasn’t specifically sorted into a playlist. I used this command:
.\yt-dlp.exe "https://www.youtube.com/@channel/videos" -S res:1080,ext:mp4:m4a -o "P:\Plex\YouTube\%(uploader)s\Uploads\%(playlist_index)s %(title)s [%(id)s].%(ext)s" --add-metadata --compat-options embed-metadata --download-archive "D:\archive.txt" --match-filter "!is_live"
This placed the rest of the videos into a playlist sub-folder just labeled “uploads”, and captures everything on the channels videos page, rather than playlists. This includes all channel videos, but by using the download-archive command anything that was already downloaded from a playlist is excluded.
Just to document a couple other yt-dlp parameters I’ve used, not specifically to get videos by playlist:
With ffmpeg transcoding to h.265 (very slow):
--exec "ffmpeg -i {} -c:v libx265 -crf 28 -c:a copy {}.mp4"
To only save part of a video, add this to ffmpeg processing:
-ss 0 -t 120
This approach also assumes videos are only assigned to one playlist, if that were not the case the resulting playlist folder structure may not be very useful.
To get Plex to use the embedded video metadata, the Personal Media Shows agent needs to be selected for the YouTube library:
Full documentation for yt-dlp is available on GitHub.
Also note that when running large downloads, YouTube may throttle the downloads.
After downloading I noticed these videos seemed to be taking up more space on my Synology drive than expected. After some investigation, I realized it’s because the yt-dlp tool downloads many temporary .part files and then stitches them into the final video. Synology was moving each deleted part file to the recycle bin, which was effectively doubling the space used on the Synology drive. After clearing the recycle bins (log in to Synology web interface > Control Panel > Shared Folder > Action > Empty All Recycle Bins), I reclaimed the extra space. I could also download to another computer and then copy over to the NAS, but that would have required a lot of free drive space on another computer.