1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 01:22:30 +00:00
mpv/core/resolve_quvi9.c
wm4 5f664d78e6 core: add libquvi 0.9 support
This adds support for libquvi 0.9.x, and these features:
- start time (part of youtube URL)
- youtube subtitles
- alternative source switching ('l' and 'L' keys)
- youtube playlists

Note that libquvi 0.9 is still in development. Although this seems to
be API stable now, it looks like there will be a 1.0 release, which is
supposed to be the next stable release and the actual successor of
libquvi 0.4.x.
2013-06-28 15:47:35 +02:00

151 lines
5.3 KiB
C

/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <assert.h>
#include <quvi.h>
#include "talloc.h"
#include "core/mp_msg.h"
#include "core/options.h"
#include "core/playlist.h"
#include "resolve.h"
static bool mp_quvi_ok(quvi_t q)
{
if (!quvi_ok(q)) {
mp_msg(MSGT_OPEN, MSGL_ERR, "[quvi] %s\n", quvi_errmsg(q));
return false;
}
return true;
}
struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts)
{
int mode = QUVI_SUPPORTS_MODE_OFFLINE;
quvi_t q = quvi_new();
if (!quvi_ok(q)) {
mp_msg(MSGT_OPEN, MSGL_ERR, "[quvi] %s\n", quvi_errmsg(q));
quvi_free(q);
return NULL;
}
struct mp_resolve_result *res = talloc_zero(NULL, struct mp_resolve_result);
if (quvi_supports(q, url, mode, QUVI_SUPPORTS_TYPE_PLAYLIST)) {
mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Checking playlist...\n");
quvi_playlist_t qp = quvi_playlist_new(q, url);
if (mp_quvi_ok(q)) {
res->playlist = talloc_zero(res, struct playlist);
while (quvi_playlist_media_next(qp)) {
char *entry = NULL;
quvi_playlist_get(qp, QUVI_PLAYLIST_MEDIA_PROPERTY_URL, &entry);
if (entry)
playlist_add_file(res->playlist, entry);
}
}
quvi_playlist_free(qp);
}
if (quvi_supports(q, url, mode, QUVI_SUPPORTS_TYPE_MEDIA)) {
mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Checking URL...\n");
quvi_media_t media = quvi_media_new(q, url);
if (mp_quvi_ok(q)) {
char *format = opts->quvi_format ? opts->quvi_format : "best";
bool use_default = strcmp(format, "default") == 0;
if (!use_default)
quvi_media_stream_select(media, format);
char *val = NULL;
quvi_media_get(media, QUVI_MEDIA_STREAM_PROPERTY_URL, &val);
res->url = talloc_strdup(res, val);
val = NULL;
quvi_media_get(media, QUVI_MEDIA_PROPERTY_TITLE, &val);
res->title = talloc_strdup(res, val);
double start = 0;
quvi_media_get(media, QUVI_MEDIA_PROPERTY_START_TIME_MS, &start);
res->start_time = start / 1000.0;
quvi_media_stream_reset(media);
while (quvi_media_stream_next(media)) {
char *entry = NULL, *id = NULL;
quvi_media_get(media, QUVI_MEDIA_STREAM_PROPERTY_URL, &entry);
quvi_media_get(media, QUVI_MEDIA_STREAM_PROPERTY_ID, &id);
if (entry) {
struct mp_resolve_src *src = talloc_ptrtype(res, src);
*src = (struct mp_resolve_src) {
.url = talloc_strdup(src, entry),
.encid = talloc_strdup(src, id),
};
MP_TARRAY_APPEND(res, res->srcs, res->num_srcs, src);
talloc_steal(res->srcs, src);
}
}
}
quvi_media_free(media);
}
if (quvi_supports(q, url, mode, QUVI_SUPPORTS_TYPE_SUBTITLE)) {
mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Getting subtitles...\n");
quvi_subtitle_t qsub = quvi_subtitle_new(q, url);
if (mp_quvi_ok(q)) {
while (1) {
quvi_subtitle_type_t qst = quvi_subtitle_type_next(qsub);
if (!qst)
break;
while (1) {
quvi_subtitle_lang_t qsl = quvi_subtitle_lang_next(qst);
if (!qsl)
break;
char *lang;
quvi_subtitle_lang_get(qsl, QUVI_SUBTITLE_LANG_PROPERTY_ID,
&lang);
// Let quvi convert the subtitle to SRT.
quvi_subtitle_export_t qse =
quvi_subtitle_export_new(qsl, "srt");
if (mp_quvi_ok(q)) {
const char *subdata = quvi_subtitle_export_data(qse);
struct mp_resolve_sub *sub = talloc_ptrtype(res, sub);
*sub = (struct mp_resolve_sub) {
.lang = talloc_strdup(sub, lang),
.data = talloc_strdup(sub, subdata),
};
MP_TARRAY_APPEND(res, res->subs, res->num_subs, sub);
talloc_steal(res->subs, sub);
}
quvi_subtitle_export_free(qse);
}
}
}
quvi_subtitle_free(qsub);
}
quvi_free(q);
if (!res->url && (!res->playlist || !res->playlist->first)) {
talloc_free(res);
res = NULL;
}
return res;
}