[vlc-commits] ytdl: extract playlist non-recursively ("flat")
Rémi Denis-Courmont
git at videolan.org
Sun Sep 27 15:16:42 CEST 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Sep 26 20:29:44 2020 +0300| [fa78491d58cac289e63d9d9dbe15ac68c298460b] | committer: Rémi Denis-Courmont
ytdl: extract playlist non-recursively ("flat")
This uses the extract-flat mode of YoutubeDL, which skips parsing
individual items within a playlist. We define a dedicated MRL scheme
to track a YoutubeDL playlist item, and parse it only when the item is
actually opened.
This has two benefits:
1) Extracting a playlist is dramatically faster.
2) Expiring media URL can be played even if the playlist is long.
This does *not* solve the remaining problem that expiring URLs cannot
be saved and replayed later.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fa78491d58cac289e63d9d9dbe15ac68c298460b
---
modules/demux/ytdl.c | 30 +++++++++++++++++++++---------
share/ytdl-extract.py | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/modules/demux/ytdl.c b/modules/demux/ytdl.c
index d0066eda24..0fcd0a0c3c 100644
--- a/modules/demux/ytdl.c
+++ b/modules/demux/ytdl.c
@@ -207,18 +207,10 @@ static void Close(vlc_object_t *obj)
json_free(&sys->json);
}
-static int OpenFilter(vlc_object_t *obj)
+static int OpenCommon(vlc_object_t *obj)
{
stream_t *s = (stream_t *)obj;
- if (s->psz_url == NULL)
- return VLC_EGENERIC;
- if (strncasecmp(s->psz_url, "http:", 5)
- && strncasecmp(s->psz_url, "https:", 6))
- return VLC_EGENERIC;
- if (!var_InheritBool(s, "ytdl"))
- return VLC_EGENERIC;
-
struct ytdl_playlist *sys = vlc_obj_malloc(obj, sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_EGENERIC;
@@ -257,6 +249,21 @@ static int OpenFilter(vlc_object_t *obj)
return VLC_SUCCESS;
}
+static int OpenFilter(vlc_object_t *obj)
+{
+ stream_t *s = (stream_t *)obj;
+
+ if (s->psz_url == NULL)
+ return VLC_EGENERIC;
+ if (strncasecmp(s->psz_url, "http:", 5)
+ && strncasecmp(s->psz_url, "https:", 6))
+ return VLC_EGENERIC;
+ if (!var_InheritBool(obj, "ytdl"))
+ return VLC_EGENERIC;
+
+ return OpenCommon(obj);
+}
+
vlc_module_begin()
set_shortname("YT-DL")
set_description("YoutubeDL")
@@ -267,4 +274,9 @@ vlc_module_begin()
/* TODO: convert to demux and enable by default */
add_bool("ytdl", false, N_("Enable YT-DL"), N_("Enable YT-DL"), true)
change_safe()
+
+ add_submodule()
+ set_capability("access", 0)
+ add_shortcut("ytdl")
+ set_callbacks(OpenCommon, Close)
vlc_module_end()
diff --git a/share/ytdl-extract.py b/share/ytdl-extract.py
index 107a77ec13..bce6a82ee9 100755
--- a/share/ytdl-extract.py
+++ b/share/ytdl-extract.py
@@ -18,6 +18,7 @@
import sys
import json
+import urllib.parse
import youtube_dl
class logger(object):
@@ -32,6 +33,7 @@ class logger(object):
def url_extract(url):
opts = {
+ 'extract_flat': True,
'logger': logger(),
'youtube_include_dash_manifest': False,
}
@@ -40,7 +42,36 @@ def url_extract(url):
# Process a given URL
infos = dl.extract_info(url, download=False)
+
+ if 'entries' in infos:
+ for entry in infos['entries']:
+ if 'ie_key' in entry and entry['ie_key']:
+ # Flat-extracted playlist entry
+ url = 'ytdl:///?' + urllib.parse.urlencode(entry)
+ entry['url'] = url;
+
+ print(json.dumps(infos))
+
+def url_process(ie_url):
+ opts = {
+ 'logger': logger(),
+ 'youtube_include_dash_manifest': False,
+ }
+
+ dl = youtube_dl.YoutubeDL(opts)
+
+ # Rebuild the original IE entry
+ entry = { }
+
+ for p in urllib.parse.parse_qsl(url[9:]):
+ entry[p[0]] = p[1]
+
+ infos = dl.process_ie_result(entry, download=False)
print(json.dumps(infos))
url = sys.argv[1]
-url_extract(url)
+
+if url.startswith('ytdl:///?'):
+ url_process(url)
+else:
+ url_extract(url)
More information about the vlc-commits
mailing list