[vlc-devel] [PATCH 3/4] ytdl: extract playlist non-recursively ("flat")
RĂ©mi Denis-Courmont
remi at remlab.net
Wed Sep 23 17:43:08 CEST 2020
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.
---
modules/stream_filter/ytdl.c | 30 +++++++++++++++++++++---------
share/ytdl-extract.py | 31 ++++++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/modules/stream_filter/ytdl.c b/modules/stream_filter/ytdl.c
index 6da83e0c08..10af6c23f7 100644
--- a/modules/stream_filter/ytdl.c
+++ b/modules/stream_filter/ytdl.c
@@ -132,19 +132,11 @@ static void Close(vlc_object_t *obj)
vlc_waitpid(sys->pid);
}
-static int OpenFilter(vlc_object_t *obj)
+static int OpenCommon(vlc_object_t *obj)
{
stream_t *s = (stream_t *)obj;
ssize_t val;
- if (s->s->pf_readdir != NULL || 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;
@@ -192,6 +184,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->s->pf_readdir != NULL || 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")
@@ -201,4 +208,9 @@ vlc_module_begin()
set_callbacks(OpenFilter, Close)
add_bool("ytdl", true, 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 74b8385d55..f166384b60 100755
--- a/share/ytdl-extract.py
+++ b/share/ytdl-extract.py
@@ -17,6 +17,7 @@
# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
import sys
+import urllib.parse
import youtube_dl
class logger(object):
@@ -68,6 +69,11 @@ def entry_extract(entry):
if 'title' in entry:
print('#EXTINF:,,' + entry['title'].splitlines()[0])
+ if 'ie_key' in fmt and fmt['ie_key']:
+ # Flat-extracted playlist entry
+ print('ytdl:///?' + urllib.parse.urlencode(fmt))
+ return
+
if 'url' in fmt:
print('#EXTVLCOPT:no-ytdl') # don't parse recursively
print(fmt['url'])
@@ -76,6 +82,7 @@ def entry_extract(entry):
def url_extract(url):
opts = {
+ 'extract_flat': True,
'logger': logger(),
'youtube_include_dash_manifest': False,
}
@@ -98,5 +105,27 @@ def url_extract(url):
# URL is a single media
entry_extract(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]
+
+ entry = dl.process_ie_result(entry, download=False)
+ print('#EXTM3U')
+ entry_extract(entry)
+
+url = sys.argv[1]
-url_extract(sys.argv[1])
+if url.startswith('ytdl:///?'):
+ url_process(url)
+else:
+ url_extract(url)
--
2.28.0
More information about the vlc-devel
mailing list