ytdl-sub: Advanced YouTube Downloading that's Worth the Effort
Automated YouTube downloading has never been this cool and fun!
I'd previously relied on Emby as my media server and Tube Archivist for fetching YouTube content. However, I've been running into persistent issues with Tube Archivist, including crashes during updates and random failures to download videos or embed thumbnails, a frustrating experience that's driven me to look for a more reliable solution. That being said, I still think Tube Archivist is a great tool, and it's probably just user error on my part (I've likely misconfigured something!) rather than any fundamental flaw in the software.
It's time to say goodbye to clunky GUI downloaders and hello to a more efficient way of downloading video content using the power of the command line and some well-organized YAML files! Yes, it may require a bit more effort upfront, but trust us, it's worth it for the flexibility and control you'll gain.
What is ytdl-sub?
ytdl-sub is a Python-based command-line tool that's specifically designed for downloading videos from YouTube and other popular video sites using the yt-dlp library. What really sets it apart, though, is its clever ability to generate metadata for media players like Kodi, Jellyfin, Plex, and Emby, making it easy to get your downloads up and running with minimal fuss all while giving you that traditional TV show feeling.
Rather Listen?
Check out the article in podcast form below!
Why download YouTube Videos?
Convenience: With ytdl-sub, users can easily download YouTube videos and playlists directly to their computer or device, without having to manually copy and paste links or navigate through the YouTube website.
Offline access: By downloading videos with ytdl-sub, users can enjoy their favorite content offline, whether they're on a plane, in an area with poor internet connectivity, or just want to reduce their data usage.
Easier playlist management: ytdl-sub allows users to download entire playlists at once, making it easy to manage and organize their favorite videos in one place.
No ads: By downloading videos directly, users can avoid watching ads and enjoy their content without interruptions.
Support for multiple formats: ytdl-sub often supports the ability to download videos in various formats (e.g. MP4, WEBM, etc.), giving users more flexibility when it comes to playing back their downloaded content.
Install YTDL-Sub on Linux
Today's focus will be on installing ytdl-sub directly on Linux, using a Debian-based system like Ubuntu. We've had success with this method and found it to work better than using Docker for our specific use case, the additional control over cron jobs was particularly beneficial.
To get started with ytdl-sub, you'll need to have FFmpeg installed on your system. Simply run apt install ffmpeg
in the terminal to get it set up. You should also be comfortable using basic Linux commands and navigating the terminal environment, especially when working with crontab. Don't worry if that sounds like a lot, I'll walk you through each step of the process here.
Navigate to the directory where you'd like to store the project files. For example, I keep mine in /mnt/utilities/ytdl-sub
. From there, use curl
to download the file, set its permissions accordingly, and then test the script to ensure everything is working as expected
curl -L -o ytdl-sub https://github.com/jmbannon/ytdl-sub/releases/latest/download/ytdl-sub
chmod +x ytdl-sub
./ytdl-sub -h
You should now see the ytdl-sub file when using the ls
command.
Now we need to create two files. The configuration file and the subscriptions YAML files.
Type nano config.yaml
and paste the following:
configuration:
working_directory: '.working_directory'
Press Ctrl X
then Y
then Enter
to save the file.
This config.yaml file tells ytdl-sub that we are storing files temporarily in this directory. All videos, metadata and images will be temporarily stored here until later transferred to your desired tv_show_directory
seen in the subscriptions file below.
Type nano subscriptions.yaml
and paste the following:
# subscriptions.yaml:
# Everything in here can be downloaded using the command:
# ytdl-sub sub subscriptions.yaml
# __preset__ is a place to define global overrides for all subscriptions
__preset__:
overrides:
# Root folder of all ytdl-sub TV Shows
tv_show_directory: "/mnt/media/Youtube/Jeremy"
# For 'Only Recent' preset, only keep vids within this range and limit
only_recent_date_range: "2months"
only_recent_max_files: 5
###################################################################
# Subscriptions nested under this will use the
# `Plex TV Show by Date` preset.
#
# Can choose between:
# - Plex TV Show by Date:
# - Jellyfin TV Show by Date:
# - Kodi TV Show by Date:
Jellyfin TV Show by Date | max_1080p:
# Sets genre tag to "Documentaries"
= Youtube | Only Recent:
"Noted": "https://www.youtube.com/@selfhosted"
Press Ctrl X
then Y
then Enter
to save the file.
This subscriptions.yaml tells ytdl-sub to fetch the latest 5 YouTube videos from my channel, covering a time frame of up to 2 months back, in 1080p MP4 format and store them in /mnt/media/Youtube/Jeremy
. The metadata is also being formatted with Jellyfin TV Show by Date
, which will allow the video content to be displayed and organized just like a traditional TV show on both Jellyfin or Emby.
You'll want to customize the file and add your favorite channels. You can do so by modifying the configuration file or subscriptions file. For more advanced modifications, however, I recommend checking out the not-so-comprehensive documentation provided in ytdl-sub's advanced guide!
How it works: The script begins by loading any custom settings from the config file, allowing users to tailor the behavior of ytdl-sub to their specific needs. Next, it consults the subscription file, where it checks for override settings that might supersede those specified in the config file. I'm aware that this can be a bit confusing, and the documentation could certainly benefit from more clarity on this point.
Let's try running a dry run on our subscription file to see if everything checks out. inside the ytdl-sub directory run the following command:
./ytdl-sub -d sub subscriptions.yaml
This will preview what a download would output but does not perform any video downloads or writes to output directories.
Given that I hadn't uploaded a new video in over a year, there were no recent videos for ytdl-sub to download. This is because I told the script to only look for videos up to 2 months back using only_recent_date_range: "2months"
However, the script executed successfully, indicating that it's working as intended even without any new content.
Want to download the files for real now? Here's what you need to do. Simply run the command again without the -d
flag as follows:
./ytdl-sub sub subscriptions.yaml
And just so you know, you don't have to name the file subscriptions.yaml. In-fact, you can name it whatever you want. I created 2 files. One for me and one for my son. Each one downloads videos we like and sends them to different directories to be served up on Emby. I named them jeremy.yaml and elijah.yaml so when I run the command I just call that file instead of subscriptions.yaml.
Not so painful, right? If you want to automate the download process, rather than running it manually each time, we can set up a simple schedule using crontab. Specifically, we'll use crontab -e
to create and edit a new cron job that will run ytdl-sub at regular intervals.
You may need to use sudo or sudo su for this but go ahead and type crontab -e
and hit Enter
. If it's your first time using crontab it may ask if you want to use nano or vim. I prefer nano so I chose that option. After choosing, you will see something like this but without the cron command. Yours may be empty other than the default commented out directions.
Arrow down to the bottom of the file and paste the cron command.
0 */3 * * * cd /mnt/utilities/ytdl-sub && ./ytdl-sub sub subscriptions.yaml
Don't forget to press Ctrl X
, Y
then Enter
to save the cron job! It's a good idea to launch crontab -e
again to double check that it did save.
This line tells the system to run the specified command every 3 hours. Simply adjust the time interval as needed, such as changing '3' to '6' for every 6 hours. The cron job will then execute the ytdl-sub script to look for new videos based on your subscriptions file. If you want to temporarily pause or stop the cron from running, just add a #
symbol at the beginning of the command, which will render it inactive. You'll notice the text will change color to indicate this. Again, don't forget to save the file before exiting!
Final Notes and Thoughts
I have to admit, when I first stumbled upon ytdl-sub a few months back, I was initially intimidated by the prospect of setting it up. The thought of customizing settings and working with YAML files seemed daunting, especially after sifting through what felt like a complex documentation set. As a result, I put off exploring ytdl-sub further until now.
While I've only scratched the surface of what this tool can do, I'm excited to dig deeper into custom settings in the near future. As it stands, I'm thrilled with how it's working out and appreciate the unique viewing experiences it provides on platforms like Emby, Jellyfin, Plex, and Kodi.
I encourage you to checkout the ytdl-sub project on github and smash that star because it is very well deserved!