aboutsummaryrefslogtreecommitdiff
path: root/build/blog/2014-11-05-list-youtube-playlist-with-youtube-dl.html
blob: 28cd21f5990a788d781e5fc65b4e3ae32a5fc5ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta content="pandoc" name="generator"/>
<meta content="Zhiming Wang" name="author"/>
<meta content="2014-11-05T10:37:58-0800" name="date"/>
<title>List YouTube playlist with youtube-dl</title>
<link href="/img/apple-touch-icon-152.png" rel="apple-touch-icon-precomposed"/>
<meta content="#FFFFFF" name="msapplication-TileColor"/>
<meta content="/img/favicon-144.png" name="msapplication-TileImage"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<link href="/css/normalize.min.css" media="all" rel="stylesheet" type="text/css"/>
<link href="/css/theme.css" media="all" rel="stylesheet" type="text/css"/>
<link href="/css/highlight.css" media="all" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="archival-notice">This blog has been archived.<br/>Visit my home page at <a href="https://zhimingwang.org">zhimingwang.org</a>.</div>
<nav class="nav">
<a class="nav-icon" href="/" title="Home"><!--blog icon--></a>
<a class="nav-title" href="/"><!--blog title--></a>
<a class="nav-author" href="https://github.com/zmwangx" target="_blank"><!--blog author--></a>
</nav>
<article class="content">
<header class="article-header">
<h1 class="article-title">List YouTube playlist with youtube-dl</h1>
<div class="article-metadata">
<time class="article-timestamp" datetime="2014-11-05T10:37:58-0800">November 5, 2014</time>
</div>
</header>
<p>Of course you are always welcome to use the <a href="https://developers.google.com/api-client-library/python/">Google APIs Client Library for Python</a> to wrestle with YouTube, which is usually pretty simple. (As an added bonus, YouTube has some <a href="https://developers.google.com/youtube/v3/code_samples/">nice runnable sample scripts</a> to get you started.) With the client library, listing videos in a YouTube playlist is a breeze.</p>
<p>However, if you don't feel like writing code yourself (I usually don't feel like writing code myself until I use something often enough and existing solutions are suboptimal), <code>youtube-dl</code> recently added the functionality to list videos in a playlist with the <code>--flat-playlist</code> option.</p>
<p><a href="https://github.com/rg3/youtube-dl/issues/4003#issuecomment-60322630">According to one of the project collaborators</a>, currently <code>--flat-playlist</code> is only helpful with the <code>-j</code> option for dumping JSON (so I suppose this feature is subject to change). For instance, <code>--flat-playlist</code> alone would emit something like this:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="op">&gt;</span> <span class="ex">youtube-dl</span> --flat-playlist <span class="st">'https://www.youtube.com/watch?v=gdOwwI0ngqQ&amp;list=PLPpZI8R1zUfrkDbmJMOBhEbJ9Td9vbV-F'</span>
[<span class="ex">youtube</span>:playlist] Downloading playlist PLPpZI8R1zUfrkDbmJMOBhEbJ9Td9vbV-F - add --no-playlist to just download video gdOwwI0ngqQ
[<span class="ex">youtube</span>:playlist] PLPpZI8R1zUfrkDbmJMOBhEbJ9Td9vbV-F: Downloading webpage
[<span class="ex">youtube</span>:playlist] PLPpZI8R1zUfrkDbmJMOBhEbJ9Td9vbV-F: Downloading page <span class="co">#1</span>
[<span class="ex">download</span>] Downloading playlist: Cam By apinknomfan
[<span class="ex">youtube</span>:playlist] playlist Cam By apinknomfan: Collected 119 video ids (downloading 119 of them)
[<span class="ex">download</span>] Downloading video <span class="co">#1 of 119</span>
[<span class="ex">download</span>] Downloading video <span class="co">#2 of 119</span>
[<span class="ex">download</span>] Downloading video <span class="co">#3 of 119</span>
[<span class="ex">download</span>] Downloading video <span class="co">#4 of 119</span>
<span class="ex">...</span></code></pre></div>
<p>which doesn't really make sense — it tells you that it collected 119 video ids, and no more. Once you have <code>-j</code> on, you get JSON data that you can parse with anything:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="op">&gt;</span> <span class="ex">youtube-dl</span> -j --flat-playlist <span class="st">'https://www.youtube.com/watch?v=gdOwwI0ngqQ&amp;list=PLPpZI8R1zUfrkDbmJMOBhEbJ9Td9vbV-F'</span>
{<span class="st">"url"</span>: <span class="st">"gdOwwI0ngqQ"</span>, <span class="st">"_type"</span>: <span class="st">"url"</span>, <span class="st">"ie_key"</span>: <span class="st">"Youtube"</span>, <span class="st">"id"</span>: <span class="st">"gdOwwI0ngqQ"</span>}
{<span class="st">"url"</span>: <span class="st">"j9l5nchv1Z8"</span>, <span class="st">"_type"</span>: <span class="st">"url"</span>, <span class="st">"ie_key"</span>: <span class="st">"Youtube"</span>, <span class="st">"id"</span>: <span class="st">"j9l5nchv1Z8"</span>}
{<span class="st">"url"</span>: <span class="st">"znW5ALwWNQw"</span>, <span class="st">"_type"</span>: <span class="st">"url"</span>, <span class="st">"ie_key"</span>: <span class="st">"Youtube"</span>, <span class="st">"id"</span>: <span class="st">"znW5ALwWNQw"</span>}
{<span class="st">"url"</span>: <span class="st">"qyE7-auTIcc"</span>, <span class="st">"_type"</span>: <span class="st">"url"</span>, <span class="st">"ie_key"</span>: <span class="st">"Youtube"</span>, <span class="st">"id"</span>: <span class="st">"qyE7-auTIcc"</span>}
<span class="ex">...</span></code></pre></div>
<p>The most straightforward way to parse this is to use a command line JSON parser, the best one being <a href="https://github.com/stedolan/jq">jq</a>:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="op">&gt;</span> <span class="ex">youtube-dl</span> -j --flat-playlist <span class="st">'https://www.youtube.com/watch?v=gdOwwI0ngqQ&amp;list=PLPpZI8R1zUfrkDbmJMOBhEbJ9Td9vbV-F'</span> <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.id'</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">'s_^_https://youtube.com/v/_'</span>
<span class="ex">https</span>://youtube.com/v/gdOwwI0ngqQ
<span class="ex">https</span>://youtube.com/v/j9l5nchv1Z8
<span class="ex">https</span>://youtube.com/v/znW5ALwWNQw
<span class="ex">https</span>://youtube.com/v/qyE7-auTIcc
<span class="ex">...</span></code></pre></div>
<p>There you go, a list of URIs you can use. Of course you can put this in a script to save some typing:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/usr/bin/env bash</span>
<span class="co"># Takes a YouTube URI to a playlist (fairly liberal, it's fine as long</span>
<span class="co"># as the playlist id can be extracted), and prints a list of URIs in a</span>
<span class="co"># YouTube playlist.</span>
<span class="co">#</span>
<span class="co"># Requires youtube-dl 2014.10.24, tested on youtube-dl</span>
<span class="co"># 2014.11.02.1. Feature subject to change.</span>
<span class="ex">youtube-dl</span> -j --flat-playlist <span class="st">"</span><span class="va">$1</span><span class="st">"</span> <span class="kw">|</span> <span class="ex">jq</span> -r <span class="st">'.id'</span> <span class="kw">|</span> <span class="fu">sed</span> <span class="st">'s_^_https://youtube.com/v/_'</span></code></pre></div>
<p><strong><em>Aside:</em></strong> I first embedded the gist here, but <a href="https://i.imgur.com/m3cr0Im.png">it looked a bit off</a>. See <a href="https://github.com/imathis/octopress/issues/1392">imathis/octopress#1392</a>.</p>
<blockquote>
<p>In the next version of the Gist tag plugin we are just downloading the gists and embedding them upon generation so we don't have to worry about GitHub going down and breaking all your gists, or changing the HTML and breaking all the styles.</p>
<p>For the time being I suggest embedding your code snippets directly if you want them to look good.</p>
</blockquote>
<p>Okay. End of aside.</p>
<p>By the way, <code>youtube-dl</code> supports playlist bulk download natively. The reason I need a list of video ids or URIs, however, is that among other things, <code>youtube-dl</code> doesn't download highest resolution DASH video by default, so I have to rely on something like <code>youtube-dl-dash</code> (<a href="https://github.com/zmwangx/sh/blob/master/youtube-dl-dash">link</a>) to download the best version.</p>
</article>
<hr class="content-separator"/>
<footer class="footer">
<span class="rfooter">
<a class="rss-icon" href="/rss.xml" target="_blank" title="RSS feed"><!--RSS feed icon--></a><a class="atom-icon" href="/atom.xml" target="_blank" title="Atom feed"><!--Atom feed icon--></a><a class="cc-icon" href="https://creativecommons.org/licenses/by/4.0/" target="_blank" title="Released under the Creative Commons Attribution 4.0 International license."><!--CC icon--></a>
<a href="https://github.com/zmwangx" target="_blank">Zhiming Wang</a>
</span>
</footer>
</body>
</html>