mirror of https://github.com/mpv-player/mpv
Drop libquvi support
No development activity (or even any sign of life) for almost a year. A replacement based on youtube-dl will probably be provided before the next mpv release. Ask on the IRC channel if you want to test. Simplify the Lua check too: libquvi linking against a different Lua version than mpv was a frequent issue, but with libquvi gone, no direct dependency uses Lua, and such a clash is rather unlikely.
This commit is contained in:
parent
423a7de676
commit
9b45b48c46
|
@ -31,9 +31,9 @@ estimated remaining duration of the source file is used.
|
|||
|
||||
Note::
|
||||
|
||||
mpv can't use ordered chapter files or libquvi-resolved URLs in EDL
|
||||
entries. Usage of relative or absolute paths as well as any protocol
|
||||
prefixes is prevented for security reasons.
|
||||
mpv can't use ordered chapter files in EDL entries. Usage of relative or
|
||||
absolute paths as well as any protocol prefixes is prevented for security
|
||||
reasons.
|
||||
|
||||
|
||||
Syntax of mpv EDL files
|
||||
|
|
|
@ -111,8 +111,6 @@ Miscellaneous
|
|||
|
||||
* Better MKV support (e.g. ordered chapters, 3D metadata).
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for playing URLs of popular streaming sites directly.
|
||||
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||
|
|
|
@ -652,10 +652,7 @@ Property list
|
|||
Full path of the currently played file.
|
||||
|
||||
``media-title``
|
||||
If libquvi is used and libquvi returns a page title for the currently
|
||||
played URL, return the page title.
|
||||
|
||||
Otherwise, if the currently played file has a ``title`` tag, use that.
|
||||
If the currently played file has a ``title`` tag, use that.
|
||||
|
||||
Otherwise, if the media type is DVD, return the volume ID of DVD.
|
||||
|
||||
|
|
|
@ -340,7 +340,7 @@ Program Behavior
|
|||
``--merge-files``
|
||||
Pretend that all files passed to mpv are concatenated into a single, big
|
||||
file. This uses timeline/EDL support internally. Note that this won't work
|
||||
for ordered chapter files or quvi-resolved URLs (such as YouTube links).
|
||||
for ordered chapter files.
|
||||
|
||||
This option is interpreted at program start, and doesn't affect for
|
||||
example files or playlists loaded with the ``loadfile`` or ``loadlist``
|
||||
|
@ -676,26 +676,6 @@ Video
|
|||
``mpv --hwdec=vdpau --vo=vdpau --hwdec-codecs=h264,mpeg2video``
|
||||
Enable vdpau decoding for h264 and mpeg2 only.
|
||||
|
||||
``--quvi-format=<best|default|...>``
|
||||
Video format/quality that is directly passed to libquvi (default: ``best``).
|
||||
This is used when opening links to streaming sites like YouTube. The
|
||||
interpretation of this value is highly specific to the streaming site and
|
||||
the video.
|
||||
|
||||
libquvi 0.4.x:
|
||||
|
||||
The only well-defined values that work on all sites are ``best``
|
||||
(best quality/highest bandwidth, default), and ``default`` (lowest
|
||||
quality).
|
||||
|
||||
The quvi command line tool can be used to find out which formats are
|
||||
supported for a given URL: ``quvi --query-formats URL``.
|
||||
|
||||
libquvi 0.9.x:
|
||||
|
||||
The following explanations are relevant:
|
||||
`<http://quvi.sourceforge.net/r/api/0.9/glossary_termino.html#m_stream_id>`_
|
||||
|
||||
``--vd-lavc-check-hw-profile=<yes|no>``
|
||||
Check hardware decoder profile (default: yes). If ``no`` is set, the
|
||||
highest profile of the hardware decoder is unconditionally selected, and
|
||||
|
@ -1244,15 +1224,6 @@ Subtitles
|
|||
a subtitle script with another video file. The ``--ass-style-override``
|
||||
option doesn't affect how this option is interpreted.
|
||||
|
||||
``--quvi-fetch-subtitles=<yes|no>``
|
||||
Toggles fetching of subtitles from streaming sites with libquvi. Disabled
|
||||
by default, because it's unreliable and slow. Note that when enabled,
|
||||
subtitles will always be fetched, even if subtitles are explicitly
|
||||
disabled with ``--no-sub`` (because you might want to enable subtitles
|
||||
at runtime).
|
||||
|
||||
Supported when using libquvi 0.9.x.
|
||||
|
||||
``--stretch-dvd-subs=<yes|no>``
|
||||
Stretch DVD subtitles when playing anamorphic videos for better looking
|
||||
fonts on badly mastered DVDs. This switch has no effect when the
|
||||
|
|
|
@ -48,7 +48,7 @@ Essential dependencies (incomplete list):
|
|||
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavresample)
|
||||
At least FFmpeg 2.1.4 or Libav 10 is required.
|
||||
- libjpeg (for screenshots)
|
||||
- libquvi if you want to play Youtube videos directly
|
||||
- Lua (strictly speaking optional, but required for the OSC pseudo-GUI)
|
||||
|
||||
Libass dependencies:
|
||||
|
||||
|
|
|
@ -173,8 +173,6 @@ options_state_machine() {
|
|||
opt_yes_no _libv4l2 "libv4l2"
|
||||
opt_yes_no _pvr "Video4Linux2 MPEG PVR"
|
||||
opt_yes_no _smb "Samba (SMB) input"
|
||||
opt_yes_no _libquvi4 "libquvi 0.4.x"
|
||||
opt_yes_no _libquvi9 "libquvi 0.9.x"
|
||||
opt_yes_no _lcms2 "LCMS2 support"
|
||||
opt_yes_no _bluray "Blu-ray support"
|
||||
opt_yes_no _dvdread "libdvdread"
|
||||
|
@ -574,17 +572,6 @@ check_pkg_config "libguess support" $_libguess LIBGUESS 'libguess >= 1.0'
|
|||
|
||||
check_pkg_config "Samba support (libsmbclient)" $_smb LIBSMBCLIENT 'smbclient >= 0.2.0'
|
||||
|
||||
check_pkg_config "libquvi 0.4.x support" $_libquvi4 LIBQUVI4 'libquvi >= 0.4.1'
|
||||
_libquvi4=$(defretval)
|
||||
|
||||
test $_libquvi4 = yes && _libquvi9=no
|
||||
check_pkg_config "libquvi 0.9.x support" $_libquvi9 LIBQUVI9 'libquvi-0.9 >= 0.9.0'
|
||||
_libquvi9=$(defretval)
|
||||
|
||||
_libquvi=no
|
||||
(test "$_libquvi9" = yes || test "$_libquvi4" = yes) && _libquvi=yes
|
||||
define_yes_no $_libquvi HAVE_LIBQUVI
|
||||
|
||||
_wlver="1.6.0"
|
||||
check_pkg_config "Wayland" $_wayland WAYLAND "wayland-client >= $_wlver wayland-cursor >= $_wlver xkbcommon >= 0.3.0"
|
||||
_wayland=$(defretval)
|
||||
|
@ -988,6 +975,7 @@ cat > $TMPC << EOF
|
|||
#define HAVE_OSX_THREAD_NAME 0
|
||||
#define HAVE_BSD_THREAD_NAME 0
|
||||
#define HAVE_NETBSD_THREAD_NAME 0
|
||||
#define HAVE_DXVA2_HWACCEL 0
|
||||
|
||||
#define DEFAULT_CDROM_DEVICE "/dev/cdrom"
|
||||
#define DEFAULT_DVD_DEVICE "/dev/dvd"
|
||||
|
|
|
@ -75,8 +75,6 @@ SOURCES-$(GL_WAYLAND) += video/out/wayland_common.c \
|
|||
|
||||
SOURCES-$(JACK) += audio/out/ao_jack.c
|
||||
SOURCES-$(JOYSTICK) += input/joystick.c
|
||||
SOURCES-$(LIBQUVI4) += stream/resolve/resolve_quvi.c
|
||||
SOURCES-$(LIBQUVI9) += stream/resolve/resolve_quvi9.c
|
||||
SOURCES-$(LIRC) += input/lirc.c
|
||||
SOURCES-$(OPENAL) += audio/out/ao_openal.c
|
||||
SOURCES-$(OSS_AUDIO) += audio/out/ao_oss.c
|
||||
|
@ -319,7 +317,6 @@ DIRS = . \
|
|||
osdep/ar \
|
||||
player \
|
||||
stream \
|
||||
stream/resolve \
|
||||
sub \
|
||||
ta \
|
||||
video \
|
||||
|
|
|
@ -202,9 +202,6 @@ const m_option_t mp_opts[] = {
|
|||
OPT_CHOICE("audio-display", audio_display, 0,
|
||||
({"no", 0}, {"attachment", 1})),
|
||||
|
||||
OPT_STRING("quvi-format", quvi_format, 0),
|
||||
OPT_FLAG("quvi-fetch-subtitles", quvi_fetch_subtitles, 0),
|
||||
|
||||
OPT_CHOICE("hls-bitrate", hls_bitrate, M_OPT_FIXED,
|
||||
({"no", 0}, {"min", 1}, {"max", 2})),
|
||||
|
||||
|
@ -647,7 +644,6 @@ const struct MPOpts mp_default_opts = {
|
|||
.sub_visibility = 1,
|
||||
.sub_pos = 100,
|
||||
.sub_speed = 1.0,
|
||||
.quvi_fetch_subtitles = 0,
|
||||
.audio_output_channels = MP_CHMAP_INIT_STEREO,
|
||||
.audio_output_format = 0, // AF_FORMAT_UNKNOWN
|
||||
.playback_speed = 1.,
|
||||
|
|
|
@ -178,8 +178,6 @@ typedef struct MPOpts {
|
|||
float sub_speed;
|
||||
int forced_subs_only;
|
||||
int stretch_dvd_subs;
|
||||
char *quvi_format;
|
||||
int quvi_fetch_subtitles;
|
||||
|
||||
int sub_fix_timing;
|
||||
char *sub_cp;
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "stream/stream.h"
|
||||
#include "demux/demux.h"
|
||||
#include "demux/stheader.h"
|
||||
#include "stream/resolve/resolve.h"
|
||||
#include "common/playlist.h"
|
||||
#include "sub/osd.h"
|
||||
#include "sub/dec_sub.h"
|
||||
|
@ -368,8 +367,6 @@ static int mp_property_media_title(void *ctx, struct m_property *prop,
|
|||
name = mpctx->opts->media_title;
|
||||
if (name && name[0])
|
||||
return m_property_strdup_ro(action, arg, name);
|
||||
if (mpctx->resolve_result)
|
||||
name = mpctx->resolve_result->title;
|
||||
if (name && name[0])
|
||||
return m_property_strdup_ro(action, arg, name);
|
||||
if (mpctx->master_demuxer) {
|
||||
|
|
|
@ -180,7 +180,6 @@ typedef struct MPContext {
|
|||
struct playlist_entry *playing; // currently playing file
|
||||
char *filename; // immutable copy of playing->filename (or NULL)
|
||||
char *stream_open_filename;
|
||||
struct mp_resolve_result *resolve_result;
|
||||
enum stop_play_reason stop_play;
|
||||
bool playback_initialized; // playloop can be run/is running
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "audio/out/ao.h"
|
||||
#include "demux/demux.h"
|
||||
#include "stream/stream.h"
|
||||
#include "stream/resolve/resolve.h"
|
||||
#include "sub/dec_sub.h"
|
||||
#include "sub/find_subfiles.h"
|
||||
#include "video/decode/dec_video.h"
|
||||
|
@ -721,69 +720,6 @@ struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename)
|
|||
STREAM_SUB);
|
||||
}
|
||||
|
||||
static void open_subtitles_from_resolve(struct MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
struct mp_resolve_result *res = mpctx->resolve_result;
|
||||
if (!res)
|
||||
return;
|
||||
for (int n = 0; n < res->num_subs; n++) {
|
||||
struct mp_resolve_sub *sub = res->subs[n];
|
||||
char *s = talloc_strdup(NULL, sub->url);
|
||||
if (!s)
|
||||
s = talloc_asprintf(NULL, "memory://%s", sub->data);
|
||||
struct track *t =
|
||||
open_external_file(mpctx, s, opts->sub_demuxer_name, STREAM_SUB);
|
||||
talloc_free(s);
|
||||
if (t) {
|
||||
t->lang = talloc_strdup(t, sub->lang);
|
||||
t->no_default = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct mp_resolve_result *resolve_url(const char *filename,
|
||||
struct mpv_global *global)
|
||||
{
|
||||
if (!mp_is_url(bstr0(filename)))
|
||||
return NULL;
|
||||
#if HAVE_LIBQUVI
|
||||
return mp_resolve_quvi(filename, global);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_resolve_contents(struct mp_log *log,
|
||||
struct mp_resolve_result *res)
|
||||
{
|
||||
mp_msg(log, MSGL_V, "Resolve:\n");
|
||||
mp_msg(log, MSGL_V, " title: %s\n", res->title);
|
||||
mp_msg(log, MSGL_V, " url: %s\n", res->url);
|
||||
for (int n = 0; n < res->num_srcs; n++) {
|
||||
mp_msg(log, MSGL_V, " source %d:\n", n);
|
||||
if (res->srcs[n]->url)
|
||||
mp_msg(log, MSGL_V, " url: %s\n", res->srcs[n]->url);
|
||||
if (res->srcs[n]->encid)
|
||||
mp_msg(log, MSGL_V, " encid: %s\n", res->srcs[n]->encid);
|
||||
}
|
||||
for (int n = 0; n < res->num_subs; n++) {
|
||||
mp_msg(log, MSGL_V, " subtitle %d:\n", n);
|
||||
if (res->subs[n]->url)
|
||||
mp_msg(log, MSGL_V, " url: %s\n", res->subs[n]->url);
|
||||
if (res->subs[n]->lang)
|
||||
mp_msg(log, MSGL_V, " lang: %s\n", res->subs[n]->lang);
|
||||
if (res->subs[n]->data) {
|
||||
mp_msg(log, MSGL_V, " data: %zd bytes\n",
|
||||
strlen(res->subs[n]->data));
|
||||
}
|
||||
}
|
||||
if (res->playlist) {
|
||||
mp_msg(log, MSGL_V, " playlist with %d entries\n",
|
||||
playlist_entry_count(res->playlist));
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the current playlist entry with playlist contents. Moves the entries
|
||||
// from the given playlist pl, so the entries don't actually need to be copied.
|
||||
static void transfer_playlist(struct MPContext *mpctx, struct playlist *pl)
|
||||
|
@ -816,17 +752,6 @@ static int process_open_hooks(struct MPContext *mpctx)
|
|||
}
|
||||
}
|
||||
|
||||
// quvi stuff
|
||||
char *filename = mpctx->stream_open_filename;
|
||||
mpctx->resolve_result = resolve_url(filename, mpctx->global);
|
||||
if (mpctx->resolve_result) {
|
||||
print_resolve_contents(mpctx->log, mpctx->resolve_result);
|
||||
if (mpctx->resolve_result->playlist) {
|
||||
transfer_playlist(mpctx, mpctx->resolve_result->playlist);
|
||||
return 1;
|
||||
}
|
||||
mpctx->stream_open_filename = mpctx->resolve_result->url;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1009,10 +934,8 @@ static void play_current_file(struct MPContext *mpctx)
|
|||
assert(mpctx->d_sub[0] == NULL);
|
||||
assert(mpctx->d_sub[1] == NULL);
|
||||
|
||||
int hooks_res = process_open_hooks(mpctx);
|
||||
talloc_steal(tmp, mpctx->resolve_result);
|
||||
if (hooks_res)
|
||||
goto terminate_playback; // quit or preloaded playlist special-case
|
||||
if (process_open_hooks(mpctx) < 0)
|
||||
goto terminate_playback;
|
||||
|
||||
int stream_flags = STREAM_READ;
|
||||
if (!opts->load_unsafe_playlists)
|
||||
|
@ -1095,7 +1018,6 @@ goto_reopen_demuxer: ;
|
|||
|
||||
|
||||
open_subtitles_from_options(mpctx);
|
||||
open_subtitles_from_resolve(mpctx);
|
||||
open_audiofiles_from_options(mpctx);
|
||||
|
||||
check_previous_track_selection(mpctx);
|
||||
|
@ -1178,9 +1100,6 @@ goto_reopen_demuxer: ;
|
|||
|
||||
// If there's a timeline force an absolute seek to initialize state
|
||||
double startpos = rel_time_to_abs(mpctx, opts->play_start);
|
||||
if (startpos == MP_NOPTS_VALUE && mpctx->resolve_result &&
|
||||
mpctx->resolve_result->start_time > 0)
|
||||
startpos = mpctx->resolve_result->start_time;
|
||||
if (startpos == MP_NOPTS_VALUE && opts->chapterrange[0] > 0) {
|
||||
double start = chapter_start_time(mpctx, opts->chapterrange[0] - 1);
|
||||
if (start != MP_NOPTS_VALUE)
|
||||
|
@ -1250,7 +1169,6 @@ terminate_playback:
|
|||
m_config_restore_backups(mpctx->mconfig);
|
||||
|
||||
mpctx->playback_initialized = false;
|
||||
mpctx->resolve_result = NULL;
|
||||
|
||||
if (mpctx->playing && mpctx->stop_play == AT_END_OF_FILE) {
|
||||
// Played/paused for longer than 1 second -> ok
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer 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.
|
||||
*
|
||||
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MP_RESOLVE_H
|
||||
#define MP_RESOLVE_H
|
||||
|
||||
struct mpv_global;
|
||||
|
||||
struct mp_resolve_result {
|
||||
char *url;
|
||||
char *title;
|
||||
|
||||
struct mp_resolve_src **srcs;
|
||||
int num_srcs;
|
||||
|
||||
double start_time;
|
||||
|
||||
struct mp_resolve_sub **subs;
|
||||
int num_subs;
|
||||
|
||||
struct playlist *playlist;
|
||||
};
|
||||
|
||||
struct mp_resolve_src {
|
||||
char *url; // can be NULL; otherwise it's the exact video URL
|
||||
char *encid; // indicates quality level, contents are libquvi specific
|
||||
};
|
||||
|
||||
struct mp_resolve_sub {
|
||||
char *url;
|
||||
char *data;
|
||||
char *lang;
|
||||
};
|
||||
|
||||
struct mp_resolve_result *mp_resolve_quvi(const char *url,
|
||||
struct mpv_global *global);
|
||||
|
||||
#endif
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
* 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <quvi/quvi.h>
|
||||
|
||||
#include "talloc.h"
|
||||
#include "common/global.h"
|
||||
#include "common/msg.h"
|
||||
#include "options/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 mpv_global *global)
|
||||
{
|
||||
QUVIcode rc;
|
||||
bool mp_url = false;
|
||||
|
||||
quvi_t q;
|
||||
rc = quvi_init(&q);
|
||||
if (rc != QUVI_OK)
|
||||
return NULL;
|
||||
|
||||
if (!strncmp(url, "mp_", 3)) {
|
||||
url += 3;
|
||||
mp_url = true;
|
||||
}
|
||||
|
||||
// Don't try to use quvi on an URL that's not directly supported, since
|
||||
// quvi will do a network access anyway in order to check for HTTP
|
||||
// redirections etc.
|
||||
// The documentation says this will fail on "shortened" URLs.
|
||||
if (quvi_supported(q, (char *)url) != QUVI_OK) {
|
||||
quvi_close(&q);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct MPOpts *opts = global->opts;
|
||||
struct mp_log *log = mp_log_new(NULL, global->log, "quvi");
|
||||
|
||||
mp_info(log, "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, req_format);
|
||||
|
||||
quvi_media_t m;
|
||||
rc = quvi_parse(q, (char *)url, &m);
|
||||
if (rc != QUVI_OK) {
|
||||
mp_err(log, "%s\n", quvi_strerror(q, rc));
|
||||
quvi_close(&q);
|
||||
talloc_free(log);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mp_resolve_result *result
|
||||
= talloc_zero(NULL, struct mp_resolve_result);
|
||||
|
||||
char *val;
|
||||
|
||||
if (quvi_getprop(m, QUVIPROP_MEDIAURL, &val) == QUVI_OK) {
|
||||
if (mp_url)
|
||||
result->url = talloc_asprintf(result, "mp_%s", val);
|
||||
else
|
||||
result->url = talloc_strdup(result, val);
|
||||
}
|
||||
|
||||
if (quvi_getprop(m, QUVIPROP_PAGETITLE, &val) == QUVI_OK)
|
||||
result->title = talloc_strdup(result, val);
|
||||
|
||||
quvi_parse_close(&m);
|
||||
quvi_close(&q);
|
||||
|
||||
if (!result->url) {
|
||||
talloc_free(result);
|
||||
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);
|
||||
|
||||
talloc_free(log);
|
||||
return result;
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
* 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 <locale.h>
|
||||
|
||||
#include <quvi.h>
|
||||
|
||||
#include "talloc.h"
|
||||
#include "common/global.h"
|
||||
#include "common/msg.h"
|
||||
#include "options/options.h"
|
||||
#include "common/playlist.h"
|
||||
#include "resolve.h"
|
||||
|
||||
static bool mp_quvi_ok(quvi_t q, struct mp_log *log)
|
||||
{
|
||||
if (!quvi_ok(q)) {
|
||||
mp_err(log, "%s\n", quvi_errmsg(q));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct mp_resolve_result *mp_resolve_quvi(const char *url,
|
||||
struct mpv_global *global)
|
||||
{
|
||||
struct mp_log *log = mp_log_new(NULL, global->log, "quvi");
|
||||
struct MPOpts *opts = global->opts;
|
||||
int mode = QUVI_SUPPORTS_MODE_OFFLINE;
|
||||
|
||||
quvi_t q = quvi_new();
|
||||
if (!quvi_ok(q)) {
|
||||
mp_err(log, "%s\n", quvi_errmsg(q));
|
||||
|
||||
quvi_free(q);
|
||||
talloc_free(log);
|
||||
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_info(log, "Checking playlist...\n");
|
||||
quvi_playlist_t qp = quvi_playlist_new(q, url);
|
||||
if (mp_quvi_ok(q, log)) {
|
||||
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_info(log, "Checking URL...\n");
|
||||
quvi_media_t media = quvi_media_new(q, url);
|
||||
if (mp_quvi_ok(q, log)) {
|
||||
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 (opts->quvi_fetch_subtitles && quvi_supports(q, url, mode, QUVI_SUPPORTS_TYPE_SUBTITLE)) {
|
||||
mp_info(log, "Getting subtitles...\n");
|
||||
quvi_subtitle_t qsub = quvi_subtitle_new(q, url);
|
||||
if (mp_quvi_ok(q, log)) {
|
||||
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, log)) {
|
||||
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);
|
||||
talloc_free(log);
|
||||
|
||||
if (!res->url && (!res->playlist || !res->playlist->first)) {
|
||||
talloc_free(res);
|
||||
res = NULL;
|
||||
}
|
||||
|
||||
// libkdecore calls setlocale(LC_ALL, ""), which breaks basic C string
|
||||
// processing functions. libkdecore can be loaded by libproxy, which is
|
||||
// used by libquvi9. This is a rather dirty workaround to reset locales.
|
||||
setlocale(LC_ALL, "C");
|
||||
|
||||
return res;
|
||||
}
|
|
@ -45,29 +45,12 @@ def check_iconv(ctx, dependency_identifier):
|
|||
return check_libs(libs, checkfn)(ctx, dependency_identifier)
|
||||
|
||||
def check_lua(ctx, dependency_identifier):
|
||||
if ctx.dependency_satisfied('libquvi4'):
|
||||
quvi_lib_storage = [ 'libquvi4' ]
|
||||
additional_lua_test_header = '#include <quvi/quvi.h>'
|
||||
additional_lua_test_code = load_fragment('lua_libquvi4.c')
|
||||
elif ctx.dependency_satisfied('libquvi9'):
|
||||
quvi_lib_storage = [ 'libquvi9' ]
|
||||
additional_lua_test_header = '#include <quvi.h>'
|
||||
additional_lua_test_code = load_fragment('lua_libquvi9.c')
|
||||
else:
|
||||
quvi_lib_storage = []
|
||||
additional_lua_test_header = ''
|
||||
additional_lua_test_code = ''
|
||||
|
||||
fragment = load_fragment('lua.c').format(
|
||||
additional_lua_test_header=additional_lua_test_header,
|
||||
additional_lua_test_code=additional_lua_test_code)
|
||||
|
||||
lua_versions = [
|
||||
( '51', 'lua >= 5.1.0 lua < 5.2.0'),
|
||||
( '51deb', 'lua5.1 >= 5.1.0'), # debian
|
||||
( '51fbsd', 'lua-5.1 >= 5.1.0'), # FreeBSD
|
||||
( 'luajit', 'luajit >= 2.0.0' ),
|
||||
# assume all our dependencies (libquvi in particular) link with 5.1
|
||||
# assume all our dependencies link with 5.1
|
||||
( '52', 'lua >= 5.2.0' ),
|
||||
( '52deb', 'lua5.2 >= 5.2.0'), # debian
|
||||
( '52fbsd', 'lua-5.2 >= 5.2.0'), # FreeBSD
|
||||
|
@ -78,11 +61,8 @@ def check_lua(ctx, dependency_identifier):
|
|||
[lv for lv in lua_versions if lv[0] == ctx.options.LUA_VER]
|
||||
|
||||
for lua_version, pkgconfig_query in lua_versions:
|
||||
if compose_checks(
|
||||
check_pkg_config(pkgconfig_query, uselib_store=lua_version),
|
||||
check_cc(fragment=fragment,
|
||||
use=[lua_version] + quvi_lib_storage,
|
||||
execute=True))(ctx, dependency_identifier):
|
||||
if check_pkg_config(pkgconfig_query, uselib_store=lua_version) \
|
||||
(ctx, dependency_identifier):
|
||||
# XXX: this is a bit of a hack, ask waf developers if I can copy
|
||||
# the uselib_store to 'lua'
|
||||
ctx.mark_satisfied(lua_version)
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
// filled on the python side with .format()
|
||||
{additional_lua_test_header}
|
||||
|
||||
static void test_lua(void) {{
|
||||
lua_State *L = luaL_newstate();
|
||||
lua_pushstring(L, "test");
|
||||
lua_setglobal(L, "test");
|
||||
}}
|
||||
|
||||
static void test_other(void) {{
|
||||
// filled on the python side with .format()
|
||||
{additional_lua_test_code}
|
||||
}}
|
||||
|
||||
int main(void) {{
|
||||
test_lua();
|
||||
test_other();
|
||||
return 0;
|
||||
}}
|
|
@ -1,3 +0,0 @@
|
|||
quvi_t q;
|
||||
if (quvi_init(&q) == QUVI_OK)
|
||||
quvi_supported(q, "http://nope");
|
|
@ -1,3 +0,0 @@
|
|||
quvi_t q = quvi_new();
|
||||
if (quvi_ok(q))
|
||||
quvi_supports(q, "http://nope", QUVI_SUPPORTS_MODE_OFFLINE, QUVI_SUPPORTS_TYPE_MEDIA);
|
16
wscript
16
wscript
|
@ -245,22 +245,6 @@ iconv support use --disable-iconv.",
|
|||
'deps': [ 'libdl' ],
|
||||
'func': check_pkg_config('smbclient'),
|
||||
'module': 'input',
|
||||
}, {
|
||||
'name': '--libquvi4',
|
||||
'desc': 'libquvi 0.4.x support',
|
||||
'groups': [ 'libquvi' ],
|
||||
'func': check_pkg_config('libquvi', '>= 0.4.1'),
|
||||
}, {
|
||||
'name': '--libquvi9',
|
||||
'desc': 'libquvi 0.9.x support',
|
||||
'groups': [ 'libquvi' ],
|
||||
'deps_neg': [ 'libquvi4' ],
|
||||
'func': check_pkg_config('libquvi-0.9', '>= 0.9.0'),
|
||||
}, {
|
||||
'name': '--libquvi',
|
||||
'desc': 'libquvi support',
|
||||
'deps_any': [ 'libquvi4', 'libquvi9' ],
|
||||
'func': check_true
|
||||
}, {
|
||||
'name' : '--lua',
|
||||
'desc' : 'Lua',
|
||||
|
|
|
@ -264,8 +264,6 @@ def build(ctx):
|
|||
( "stream/tv.c", "tv" ),
|
||||
( "stream/tvi_dummy.c", "tv" ),
|
||||
( "stream/tvi_v4l2.c", "tv-v4l2"),
|
||||
( "stream/resolve/resolve_quvi.c", "libquvi4" ),
|
||||
( "stream/resolve/resolve_quvi9.c", "libquvi9" ),
|
||||
|
||||
## Subtitles
|
||||
( "sub/ass_mp.c", "libass"),
|
||||
|
|
Loading…
Reference in New Issue