[vlc-commits] ytdl: avoid intermediate playlist for single media

Rémi Denis-Courmont git at videolan.org
Mon Sep 28 20:14:36 CEST 2020


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Sep 20 21:27:42 2020 +0300| [737a4bf18c771bc4f9d5b6ecd8bbcdbd035de07f] | committer: Rémi Denis-Courmont

ytdl: avoid intermediate playlist for single media

Rather than exposing a playlist with a single item, this wraps the
media at the found URL. This allows the actual media URL to be
resolved and possibly refreshed every time.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=737a4bf18c771bc4f9d5b6ecd8bbcdbd035de07f
---

 modules/demux/ytdl.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/modules/demux/ytdl.c b/modules/demux/ytdl.c
index 589218b7f4..a6dce10213 100644
--- a/modules/demux/ytdl.c
+++ b/modules/demux/ytdl.c
@@ -30,6 +30,7 @@
 
 #include "json/json.h"
 #include <vlc_common.h>
+#include <vlc_demux.h>
 #include <vlc_stream.h>
 #include <vlc_fs.h>
 #include <vlc_input_item.h>
@@ -75,6 +76,7 @@ FILE *vlc_popen(pid_t *restrict pid, const char *argv[])
 
 struct ytdl_playlist {
     struct json_object json;
+    stream_t *source;
 };
 
 static const struct json_object *PickFormat(stream_t *s,
@@ -236,11 +238,55 @@ static int Control(stream_t *s, int query, va_list args)
     return VLC_SUCCESS;
 }
 
+static int DemuxNested(stream_t *s)
+{
+    struct ytdl_playlist *sys = s->p_sys;
+
+    return demux_Demux(sys->source);
+}
+
+static int ControlNested(stream_t *s, int query, va_list args)
+{
+    struct ytdl_playlist *sys = s->p_sys;
+
+    switch (query) {
+        case DEMUX_GET_META: {
+            vlc_meta_t *meta = va_arg(args, vlc_meta_t *);
+
+            GetMeta(meta, &sys->json);
+            return demux_Control(sys->source, query, meta);
+        }
+
+        default:
+            return demux_vaControl(sys->source, query, args);
+    }
+}
+
+static stream_t *vlc_demux_NewURL(vlc_object_t *obj, const char *url,
+                                  es_out_t *out)
+{
+    stream_t *stream = vlc_stream_NewURL(obj, url);
+
+    if (stream != NULL) {
+        demux_t *demux = demux_New(obj, "any", stream, out);
+
+        if (demux != NULL)
+            return demux;
+
+        vlc_stream_Delete(stream);
+    }
+
+    return NULL;
+}
+
 static void Close(vlc_object_t *obj)
 {
     stream_t *s = (stream_t *)obj;
     struct ytdl_playlist *sys = s->p_sys;
 
+    if (sys->source != NULL)
+        vlc_stream_Delete(sys->source);
+
     json_free(&sys->json);
 }
 
@@ -281,8 +327,41 @@ static int OpenCommon(vlc_object_t *obj)
     }
 
     s->p_sys = sys;
-    s->pf_readdir = ReadDir;
-    s->pf_control = Control;
+    sys->source = NULL;
+
+    if (json_get(&sys->json, "entries") != NULL) {
+        /* Playlist */
+        s->pf_readdir = ReadDir;
+        s->pf_control = Control;
+        return VLC_SUCCESS;
+    }
+
+    /* Redirect if there is a single URL, so that we can refresh it every
+     * time it is opened.
+     */
+    const struct json_object *fmt = PickFormat(s, &sys->json);
+    stream_t *demux = NULL;
+
+    if (fmt != NULL) {
+        const char *url = json_get_str(fmt, "url");
+
+        if (url != NULL) {
+            var_Create(obj, "ytdl", VLC_VAR_BOOL);
+            demux = vlc_demux_NewURL(obj, url, s->out);
+
+            if (demux == NULL)
+                msg_Err(s, "cannot open URL: %s", url);
+            else
+                msg_Dbg(s, "redirecting to: %s", url);
+         }
+    }
+
+    if (demux == NULL)
+        return VLC_EGENERIC;
+
+    s->pf_demux = DemuxNested;
+    s->pf_control = ControlNested;
+    sys->source = demux;
     return VLC_SUCCESS;
 }
 



More information about the vlc-commits mailing list