Downloading your YouTube Watch Later Playlist with yt-dlp

I’m somewhat moving to watching YouTube videos in my JellyFin server. This helps avoid algorithmic-based distractions, reduce the SWARM of ads shoved down my throat without premium, and gets me background play on mobile.
We’re working in the Discord server to find the best path for automating your subscriptions being piped to JellyFin (ytdl-sub currently winning) but for Watch Later - where I watch MOST of my videos, not always from subscriptions - it’s a bit messier.
I’ve found the path to be:

yt-dlp https://www.youtube.com/playlist?list=WL --skip-download --ignore-errors --flat-playlist --print-to-file webpage_url urls.txt

This pipes all of the videos in your Watch Later list into a text file. I had to do this for a few reasons:

  • Watch Later is not a unique playlist ID, so browser cookies were needed
  • My WL list is 5000+ videos, so after 100 or so yt-dlp’s access to the cookie expired and I instead ended up with a flood of folders of partial/incomplete downloads and no way to know which was which

Once I have the URL list, I can feed them into yt-dlp with:

yt-dlp -a urls.txt

or I may actually use Jdownloader2 for this, as I’m still worried about encountering the issue with downloading 5K videos at once, and the download manager UI of Jdownloader2 would allow me to identify and restart the ones that failed.
Alternatively, I could/may just break the list into chunks and download in chunks to avoid the issue.

Hope this helps someone!

NOTE: There is some widespread issue with 4K copies not being available to yt-dlp lately. The latest nightly update TRIES to fix this, but has not fixed it for me. Since this is purely for casual viewing and not true archival, I’m fine with it I guess. https://www.reddit.com/r/youtubedl/comments/1n1ymb9/ytdlp_release_20250827/

If you want to bulk-remove videos from your Watch Later playlist, open the playlist in a browser and run this in the JavaScript console:

setInterval(function () {
    video = document.getElementsByTagName('ytd-playlist-video-renderer')[0];

    video.querySelector('#primary button[aria-label="Action menu"]').click();

    var things = document.evaluate(
        '//span[contains(text(),"Remove from")]',
        document,
        null,
        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
        null
    );

    for (var i = 0; i < things.snapshotLength; i++) 
    {
        things.snapshotItem(i).click();
    }
}, 500);

Works for me in FireFox as of August 28, 2025.
Obligatory “don’t run code you aren’t familiar with in your browser, that’s a massive security risk” - but this one’s pretty easy to understand what it’s doing.

Also as a fun bit, to split my 5000+ line “urls.txt” into separate 100-line text files to feed to yt-dlp 100 videos at a time (to avoid rate-limiting), I used this Windows batch script:

@echo off
setlocal enabledelayedexpansion

set "input_file=urls.txt"
set "lines_per_file=100"
set "line_count=0"
set "file_count=1"
set "output_file=output1.txt"

if not exist "%input_file%" (
    echo Error: The file "%input_file%" does not exist.
    goto :eof
)

echo Splitting "%input_file%"...

for /f "delims=" %%a in ('find /n /v "" ^< "%input_file%"') do (
    set "line_content=%%a"
    set "line_content=!line_content:*]=!"
    echo !line_content!>>!output_file!
    set /a line_count+=1
    if !line_count! equ !lines_per_file! (
        set /a file_count+=1
        set "output_file=output!file_count!.txt"
        set "line_count=0"
    )
)

echo Done. Files created.
endlocal


So long, Watch Later! Fresh start after 12 years.