Create your own Netflix for nerds

Personal development is a journey that never ends. Here's one of the many ways that I keep my mental tools sharp.

Featured image

I love to learn. I strongly believe that if you’re not learning something new, then you’re becoming obsolete; this is especially true in the tech industry. Personal development is a journey that never ends. Here’s one of the many ways that I keep my mental tools sharp.

Downloading content for offline viewing

Most notable training platforms provide you with two basic ways to consume their content; A web-based media player on their website, and a companion mobile app.

For content provided via a web browser, I find this to be incredibly restrictive. Sitting at my desk in the study on my desktop computer isn’t a great environment for learning. I want my learning environment to be relaxing, and I want the display the content on a large screen so I can see what’s going on. This is especially true any content in which the educator is displaying code.

As far as companion mobile applications go, these can be hit or miss. Every training platform does it a different way, with different apps, which have different features. Some platforms either don’t have a mobile app at all or make you pay for it!

When it comes to free content such as YouTube, you’ve got the same two methods to consume the content. There’s a web client and a mobile client and that’s great, but what about other free sources of content, such as Channel9? All they have is a web player, and it’s very clunky at best.

When you begin to download videos and store them on your local network, it opens up a large number of possibilities relating to the devices that can stream the content and how you can consume it. By sending all your content to a single media server, you’re able to consume the content from multiple sources, on more devices (such as smart TVs), in a uniform way.

Media Server: Plex

Two of the primary ways that I consume video content is in my living room on my big screen TV, and on the bus on my way to work. I like to get up early and learn something new while I have my breakfast and morning coffee and continue watching the same video(s) on my commute to the office.

I’ve got a NAS device in which I store all the downloaded content, and I use Plex to stream to my TV and sync files to my mobile device for the bus ride.

Plex keeps track of which videos I’ve already watched as well as the playback position of each video, so I can pick up at the exact playback location as I transfer between devices.

Setting up and configuring Plex is outside the scope of this post, but here’s a step-by-step guide to get you started.


youtube-dl is a python script that which does exactly what it says on the tin. It downloads videos from YouTube. But, it supports downloading videos from hundreds of sources in addition to just YouTube.

The script supports some my favorite and most popular learning sites such as:

You’ll still need a subscription to download content from some of those subscription services, but if you own one or you’re lucky enough for your employer to provide one for you, youtube-dl allows you to maximize the investment by allowing you to make the content more conveniently accessible.

First install youtube-dl:

pip3 install --upgrade youtube-dl

Then you can download videos like this:

youtube-dl <url of video or playlist>

Downloading free content


YouTube is a fantastic source of cat videos educational content, and I use it as a very efficient self-improvement tool. Whether it’s keeping up to date on new tech releases, learning how to work more productively by creating positive habits, or deep diving into the technical nuance of a product or technology, YouTube is a valuable and renewable resource.

When there’s been a recent major conference like Microsoft Ignite, Microsoft Build or Defcon, the host of the conference usually uploads recordings of the sessions to YouTube on their official channels.

I like to sift through different channels and add videos that look interesting to my own private playlist. Then I use youtube-dl to download all the videos from my playlist all at once.



Channel9 is an often overlooked gold mine of developer related learning content. From ML to AI, or from blockchain to Blazor - it’s all there and it’s all free!

youtube-dl supports Channel9 natively. You can download videos like this:


You can even download all videos from an entire Microsoft Event by just pointing youtube-dl at the event playlist.

Don't forget to check out the Channel9 shows !

Downloading subscription content

Some subscription services may prohibit the downloading of their content.
You are responsible for making sure that you comply with the terms of use detailed by that service.

Downloading subscription content is very similar to the free content, except you need to specify your username and password for the subscription website. This can be achieved using the --username and --password parameters.

Example: Username & Password

youtube-dl needs to know how to log in and access the content. This can be provided by using the --username and --password parameters.

youtube-dl --username "[email protected]" --password "atotallysecretpassword"

Example: Exporting cookies

Sometimes the plain old username and password method may not work, and youtube-dl may throw errors like this one that I got with LinkedIn Learning:

youtube-dl --username "[email protected]" --password "atotallysecretpassword"

ERROR: An extractor error has occurred. (caused by KeyError(u'JSESSIONID',)); please report this issue on Make sure you are using the latest version; see  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

To fix that, try feeding youtube-dl the cookies for that website.

  1. Download and install cookies.txt browser extension from the Chrome web store. (Firefox version) file

  2. Login to the training platform and click the browser extension to view the cookies for that site.

  3. Click the link to download the cookies for the active tab. file

  4. Use the --cookies parameter and point to your cookies file

youtube-dl --cookies /path/to/cookies.txt
The following error may occurr if the cookies.txt file is malformed.
ERROR: An extractor error has occurred. (caused by KeyError('JSESSIONID',)); please report this issue on <> . Make sure you are using the latest version; type youtube-dl -U to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
I have found that this can happen when using the Google Chrome extension to export cookies.
To resolve the problem, use Firefox.

Formatting output

youtube-dl supports a wide range of output options in the form of output templates.

Output templates let you specify how to save the downloaded content in terms of directories and file names.

You can specify an output template by using the -o parameter.

Formatting the directories and names of the files is important, as this will be how the media is displayed within Plex. Make it easy on yourself to locate specific videos and browse your content library by using an output template that works nicely with your media server.

Experiment with the output template variables to find one that makes you happy.

Here’s one that I use often.

 -o "/mnt/c/Users/Casey/Videos/%(playlist)s/%(chapter_number)s. %(chapter)s/%(playlist_index)s. %(title)s.%(ext)s"


Viewing your content

Now that you’ve downloaded the content that you want to watch, copy it to a central location that’s accessible by your media centre. In my case, I copy it to my NAS. I’ve configured a share that’s accessible by Plex.


Now you can stream that content to any Plex player, such as the built-in Plex app on a SmartTV or the Plex app on the Xbox One or Playstation 4.


If you’re a Plex Pass subscriber, you can synchronize videos from your Plex library to your mobile device for viewing on the go.



Sometimes things don’t work the way you’d like. Here’s a couple of fixes to some common problems.


youtube-dl --username "[email protected]" --password "yourPassword" --verbose --sleep-interval 120

The argument --sleep-interval 120 is important. It means that the program will wait for 120s (2 minutes) before it downloads the next video. If you don’t use this flag Pluralsight will ban you because you are doing too many requests within too a short period.

We have blocked your account because our security systems have flagged your Pluralsight account for an unusual amount activity. This does mean a high volume of requests that are in the realm of a request every 10-30 seconds for a prolonged period of time. Please note that this high volume of activity is in violation of our terms of service

LinkedIn Learning

When downloading videos from LinkedIn Learning, you may receive the following error on the 5th or so video.

ERROR: No video formats found; please report this issue on Make sure you are using the latest version; see  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
Traceback (most recent call last):
  File "/home/casey/.local/lib/python3.6/site-packages/youtube_dl/", line 796, in extract_info
    ie_result = ie.extract(url)
  File "/home/casey/.local/lib/python3.6/site-packages/youtube_dl/extractor/", line 530, in extract
    ie_result = self._real_extract(url)
  File "/home/casey/.local/lib/python3.6/site-packages/youtube_dl/extractor/", line 127, in _real_extract
    self._sort_formats(formats, ('width', 'height', 'source_preference', 'tbr', 'abr'))
  File "/home/casey/.local/lib/python3.6/site-packages/youtube_dl/extractor/", line 1327, in _sort_formats
    raise ExtractorError('No video formats found')
youtube_dl.utils.ExtractorError: No video formats found; please report this issue on Make sure you are using the latest version; see  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

I’ve found this problem occurs when accessing LinkedIn learning from an “enterprise” account that’s provided by a third party. This may be the case if your employer provides you with LinkedIn Learning content after you link your personal LinkedIn account with your organization and sign in via single sign-on (SSO).

From what I can tell, the web requests to LinkedIn Learning are different between a regular premium account and an “enterprise” account and youtube-dl only supports the former by default.

The requests to enterprise content include an additional header in each web request; x-li-identity which is a base64 encoded representation of some additional account information.

We can get youtube-dl to work with an enterprise account by using the --add-header parameter and specifying the value of the x-li-identity header.

  1. Log in to LinkedIn Learning using your enterprise account.
  2. Press F12 to open the browser tools.
  3. Click the Network tab, and refresh the page. This will display all the web requests being made by the browser. file
  4. Press CTRL + F and search for x-li-identity. This will display all of the web requests that contain the header we’re looking for. file
  5. Click on one of the search results. This will display the web request that contains the header, and highlight the header and its value. file
  6. Double-Click the value, then Right-Click and select Copy. Make sure you’re selecting the entire value. Sometimes it may not select any non-alphanumeric characters at the end of the string. file
  7. Use youtube-dl and include the --add-header parameter
youtube-dl --cookies </path/to/cookies.txt> --add-header x-li-identity:<base64 encoded value> <linkedin learning url>