27

In youtube-dl, I'm trying to get only the playlist content (should be 600+ entries) from a URL, thus:

youtube-dl -i -v --flat-playlist --skip-download https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr

which according to the man page should list playlist entries while preventing file download.

Instead it hangs, after producing this output:

~ $ youtube-dl -i -v --flat-playlist --skip-download https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr  
[1] 4531  
~ $ [debug] System config: []  
[debug] User config: []  
[debug] Custom config: []  
[debug] Command-line args: ['-i', '-v', '--flat-playlist', '--skip-download', 'https://www.youtube.com/watch?v=CNotezuR73g']  
[debug] Encodings: locale UTF-8, fs utf-8, out UTF-8, pref UTF-8  
[debug] youtube-dl version 2018.07.10  
[debug] Python version 3.6.6 (CPython) - Linux-4.17.6-1-ARCH-x86_64-with-arch  
[debug] exe versions: ffmpeg 4.0.1, ffprobe 4.0.1, rtmpdump 2.4  
[debug] Proxy map: {}  
[youtube] CNotezuR73g: Downloading webpage  
[youtube] CNotezuR73g: Downloading video info webpage  
[debug] Default format spec: bestvideo+bestaudio/best  

How should I do this?

2
  • 1
    I'm on Windows so perhaps this doesn't apply to Linux, but I had to change the url to https://www.youtube.com/playlist?list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr Also, see this: archive.zhimingwang.org/blog/…
    – wysiwyg
    Commented Jul 19, 2018 at 22:35
  • Comments seem to be limited to one line so I must make a separate post instead, see below.
    – user985675
    Commented Jul 20, 2018 at 19:21

5 Answers 5

42

Did u read the page wysiwig suggested in his comment? (thanks @wysiwig!)

List Youtube playlist with youtube-dl

Anyway, here I'll try to explain what you could do (extracted from the previous web site)

Try using this command:

youtube-dl -j --flat-playlist "https://<yourYoutubePlaylist>" | jq -r '.id' | sed 's_^_https://youtu.be/_' > result.log

This will produce an output similar to this in result.log:

https://youtu.be/0gvUCLL-UGE
https://youtu.be/CPV7zcUy4J0
https://youtu.be/4wyZNwIrH9I
...

which should be what you need (a list of discrete links to YT videos).

Command explanation With the -j option youtube-dl will produce a JSON output which contains all the information about the link you pass (a playlist in this case).

This JSON output is then passed to jq JSON processor (you have to install it before see JQ website) searching for all the "id" keys contained in the JSON output (0gvUCLL-UGE,CPV7zcUy4J0,4wyZNwIrH9I,...). We then pass those "id"s to sed which will prefix each of them with https://youtu.be/ giving the result I shown before.

Note 1:To install JQ you can simply use: sudo apt-get install jq

Note 2:This approach works for Youtube only.

5
  • After I got tired of dutifully looking up movie names on imdb and downloading them individually, I settled on your solution as the most convenient, but with the insertion of another sed command before jq to eliminate all the 'Private videos', thus: youtube-dl -j --flat-playlist "https://<yourYoutubePlaylist>"|sed '/Private video/d'|jq -r '.id'|sed 's_^_https://youtu.be/_' > result.log
    – user985675
    Commented Dec 6, 2018 at 22:56
  • 2
    you can format the url with jq without using sed with jq -r '"https://youtu.be/\(.id)"'
    – norcalli
    Commented May 30, 2019 at 1:09
  • Can i get output like the following : youtu.be/0gvUCLL-UGE | video title youtu.be/CPV7zcUy4J0 | video title youtu.be/4wyZNwIrH9I | video title
    – Neel
    Commented Dec 14, 2020 at 22:25
  • How to skip this jq? I get error jq : The term 'jq' is not recognized as the name of a cmdlet,
    – Peter.k
    Commented Apr 26, 2022 at 11:41
  • without jq: youtube-dl --get-id --flat-playlist "<playlist-url>" | awk '{print "https://youtu.be/" $0}'
    – ddelange
    Commented Oct 12, 2022 at 11:48
8

@wysiwig's method does produce output on linux, but not what I sought, thus :

$ youtube-dl --flat-playlist --skip-download https://www.youtube.com/playlist?list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr  

Output :

[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading webpage
[download] Downloading playlist: Full Length Arthouse Movies
[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading page #1
[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading page #2
[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading page #3
[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading page #4
[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading page #5
[youtube:playlist] PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr: Downloading page #6
[youtube:playlist] playlist Full Length Arthouse Movies: Downloading 636 videos
[download] Downloading video 1 of 636
[download] Downloading video 2 of 636
[download] Downloading video 3 of 636
...

What I really wanted to get from the playlist are the the video-names, so that I could pick out only those I want to download, which I get with :

$ youtube-dl -i --get-filename --skip-download https://www.youtube.com/playlist?list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr  

Output :

The Waiters (full length MOVIE, entire feature film, full film) _watch full movies for free-CNotezuR73g.mp4
Malcolm X (MORGAN FREEMAN, Full Movie, Englisch, Film in Full Length) _watch full movies for free-3C8j1C7HMj8.mp4
The Arizona Kid - Western, Full Movie, Full Length Feature Film starring ROY ROGERS, Classic Movies-8McZ6G2Uud8.mp4
Desperado Man aka Sagebrush Trail (Western Movie, Full Length Movie, Feature Film, Classic Movie)-7udmB5M6IIE.mp4
...

2

It appears you're not quoting the URL. Always quote URLs. On any operating system.

In your example, the issue is clearly visible:

~ $ youtube-dl -i -v --flat-playlist --skip-download https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr
[1] 4531

[1] 4531 means a job (ID 1) has been started and is running with PID 4531.

This command line is more or less equivalent to:

youtube-dl -i -v --flat-playlist --skip-download https://www.youtube.com/watch?v=CNotezuR73g &
list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr

The ampersand at the end means line 1 will be executed in the background. It’ll still be connected to your shell, so you’ll see its output. It’s probably not hanging, just finished: It’s just a link to a video after all.

Line 2 is a variable assignment in Bash. It’ll define a variable called list if it doesn’t already exist. It’ll be usable like this:

~ $ echo $list
PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr

The correct command line you want to use is:

youtube-dl -i -v --flat-playlist --skip-download "https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr"
2
  1. Make sure you have updated to the latest youtube-dl as it's updated frequently and old versions can stop working properly

    pip install --upgrade youtube_dl
    
  2. Enter appropriate command for output you want (videos NOT downloaded)

    Video id's only:

    youtube-dl --get-id https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr
    

    Title only:

    youtube-dl --get-title https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr
    

Can use either url format:

https://www.youtube.com/watch?v=CNotezuR73g&list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr https://www.youtube.com/playlist?list=PLm9l7EEbJuhyDYNuItj3sG8h3xAZbjIxr

The above commands just print to the screen (standard out). If you want to redirect to a file:

youtube-dl --get-id https://www.youtube.com/playlist?list=<playlist id>  > file.txt

Or print to screen AND redirect to file:

youtube-dl --get-id https://www.youtube.com/playlist?list=<playlist id> | tee file.txt

Ctrl-C to cancel the process

0

My solution. Uses perl, but does an entire channel:

#!/usr/bin/perl
# Make a plain text list of the videos in all the playlists of a
# YouTube channel, using yt-dlp. The crucial item is the "/playlists"
# after the channel URL.
use strict;
use warnings 'all';
use open qw/:std :encoding(utf8)/;
use JSON;
my $prog = q(yt-dlp --dump-json --ignore-errors --flat-playlist);
my $chan = q(https://www.youtube.com/@jidanni2);
for ( split /\n/, qx!$prog $chan/playlists! ) {
    for ( decode_json $_) {
        printf "==== %s |%s\n", $_->{url}, $_->{title};
        my $c;
        for ( split /\n/, qx!$prog $_->{url}! ) {
            for ( decode_json $_) {
                printf "%03d|%s|%s\n", ++$c, $_->{id}, $_->{title};
            }
        }
    }
}

Output:

==== https://www.youtube.com/playlist?list=PLU... |其他 Etc.
001|Pqz7tTlNLB8|積丹尼 (Dan Jacobson) 在 HackingThursday 的 ed 快講
002|r8VJXO195R8|mini Debian Camp 2009 Day 1
003|rrrrrxxxxxx|Nibblesford Olympics
==== https://www.youtube.com/playlist?list=PLURD44... |Ernest P. Worrell
001|xxxxyyyyyyy|Ernest goes to the laundromat
002|xxxxyyyyyzz|Ernest goes to the taxidermist
etc.

Runs blazingly fast! I don't think there is an even faster way to do this.

Space added at end of each playlist URL in output, for easier mouse grabbing.

Playlist indexes (001, 002...) are not official %(playlist_index)'s but good enough estimates, as we want the speed of using --flat-playlist .

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .