[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