diff --git a/mpvcore/command.c b/mpvcore/command.c index a5f66aae2b..a99dd3dcab 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -496,17 +496,22 @@ static int mp_property_edition(m_option_t *prop, int action, void *arg, } static struct mp_resolve_src *find_source(struct mp_resolve_result *res, - char *url) + char *encid, char *url) { if (res->num_srcs == 0) return NULL; int src = 0; for (int n = 0; n < res->num_srcs; n++) { - if (strcmp(res->srcs[n]->url, res->url) == 0) { + char *s_url = res->srcs[n]->url; + char *s_encid = res->srcs[n]->encid; + if (url && s_url && strcmp(url, s_url) == 0) { src = n; break; } + // Prefer source URL if possible; so continue in case encid isn't unique + if (encid && s_encid && strcmp(encid, s_encid) == 0) + src = n; } return res->srcs[src]; } @@ -514,11 +519,12 @@ static struct mp_resolve_src *find_source(struct mp_resolve_result *res, static int mp_property_quvi_format(m_option_t *prop, int action, void *arg, MPContext *mpctx) { + struct MPOpts *opts = mpctx->opts; struct mp_resolve_result *res = mpctx->resolve_result; if (!res || !res->num_srcs) return M_PROPERTY_UNAVAILABLE; - struct mp_resolve_src *cur = find_source(res, res->url); + struct mp_resolve_src *cur = find_source(res, opts->quvi_format, res->url); if (!cur) return M_PROPERTY_UNAVAILABLE; diff --git a/mpvcore/resolve.h b/mpvcore/resolve.h index 91684df250..7a60b29114 100644 --- a/mpvcore/resolve.h +++ b/mpvcore/resolve.h @@ -38,7 +38,7 @@ struct mp_resolve_result { }; struct mp_resolve_src { - char *url; + char *url; // can be NULL; otherwise it's the exact video URL char *encid; // indicates quality level, contents are libquvi specific }; diff --git a/mpvcore/resolve_quvi.c b/mpvcore/resolve_quvi.c index 9e98f2a992..00279c568f 100644 --- a/mpvcore/resolve_quvi.c +++ b/mpvcore/resolve_quvi.c @@ -23,6 +23,17 @@ #include "mpvcore/options.h" #include "resolve.h" +static void add_source(struct mp_resolve_result *res, const char *url, + const char *encid) +{ + struct mp_resolve_src *src = talloc_ptrtype(res, src); + *src = (struct mp_resolve_src) { + .url = talloc_strdup(src, url), + .encid = talloc_strdup(src, encid), + }; + MP_TARRAY_APPEND(res, res->srcs, res->num_srcs, src); +} + struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts) { QUVIcode rc; @@ -49,14 +60,15 @@ struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts) mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Checking URL...\n"); + const char *req_format = opts->quvi_format ? opts->quvi_format : "best"; + // Can use quvi_query_formats() to get a list of formats like this: // "fmt05_240p|fmt18_360p|fmt34_360p|fmt35_480p|fmt43_360p|fmt44_480p" // (This example is youtube specific.) // That call requires an extra net access. quvi_next_media_url() doesn't // seem to do anything useful. So we can't really do anything useful // except pass through the user's format setting. - quvi_setopt(q, QUVIOPT_FORMAT, opts->quvi_format - ? opts->quvi_format : "best"); + quvi_setopt(q, QUVIOPT_FORMAT, req_format); quvi_media_t m; rc = quvi_parse(q, (char *)url, &m); @@ -89,5 +101,11 @@ struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts) result = NULL; } + // Useful for quvi-format cycling + add_source(result, NULL, "default"); + add_source(result, NULL, "best"); + if (strcmp(req_format, "best") != 0 && strcmp(req_format, "default") != 0) + add_source(result, NULL, req_format); + return result; }