summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@mplayer2.org>2012-03-02 20:24:34 +0100
committerwm4 <wm4@mplayer2.org>2012-07-28 22:05:34 +0200
commit7a06095dc3e5a3590f489aad3619dc6023a5b0f5 (patch)
tree961037d9f4542b5d42e30ab67b8766e1ea6cc464
parent42c3a300082f5dfbbd09818d149331ff45fd5892 (diff)
downloadmpv-7a06095dc3e5a3590f489aad3619dc6023a5b0f5.tar.bz2
mpv-7a06095dc3e5a3590f489aad3619dc6023a5b0f5.tar.xz
Add support for playing video from streaming sites with libquvi
This enables playing URLs from libquvi supported streaming sites directly, e.g. "mplayer http://www.youtube.com/watch?v=...." Anything opened with mplayer is checked with libquvi. If it looks like a URL of a supported streaming site, libquvi is used to extract the media URL, which is then passed to the lower level mplayer code instead of the HTML URL. Hopefully the libquvi URL checker works well enough that it doesn't cause any problems with normal URLs, files, or whatever else mplayer's stream layer accepts. Add the --libquvi-format option. the option value is directly passed to libquvi as requested format. The only values that seem to work for any streaming site seem to be "best" (best quality) and "default" (lowest quality). The mplayer option defaults to "best" (overriding libquvi's default). Outstanding issues: - Does libquvi checking every opened file really not cause problems? Should there be a runtime option to disable libquvi use? (Probably not an issue.) - Should we check/set the supported protocol? By default libquvi has support for all protocols enabled. In the worst case, it might return an URL using a protocol not supported by mplayer, even though it could extract URLs with other protocols too. (Probably not an issue.) - Somehow export metadata (like media title) to the mplayer frontend?
-rw-r--r--cfg-mplayer.h2
-rwxr-xr-xconfigure19
-rw-r--r--options.h1
-rw-r--r--stream/open.c71
4 files changed, 91 insertions, 2 deletions
diff --git a/cfg-mplayer.h b/cfg-mplayer.h
index 6044b86645..3aacdd274f 100644
--- a/cfg-mplayer.h
+++ b/cfg-mplayer.h
@@ -520,6 +520,8 @@ const m_option_t common_opts[] = {
OPT_MAKE_FLAGS("hr-mp3-seek", hr_mp3_seek, 0),
+ OPT_STRING("quvi-format", quvi_format, 0),
+
{ "rawaudio", (void *)&demux_rawaudio_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
{ "rawvideo", (void *)&demux_rawvideo_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
diff --git a/configure b/configure
index d51ba56a21..0d407c693d 100755
--- a/configure
+++ b/configure
@@ -334,6 +334,7 @@ Optional features:
--enable-winsock2_h enable winsock2_h [autodetect]
--enable-smb enable Samba (SMB) input [autodetect]
--enable-live enable LIVE555 Streaming Media [disable]
+ --enable-libquvi enable libquvi [autodetect]
--enable-nemesi enable Nemesi Streaming Media [autodetect]
--enable-lcms2 enable LCMS2 support [autodetect]
--disable-vcd disable VCD support [autodetect]
@@ -612,6 +613,7 @@ _pvr=auto
networking=yes
_winsock2_h=auto
_smb=auto
+_libquvi=auto
_joystick=no
_xvid=auto
_libnut=auto
@@ -935,6 +937,8 @@ for ac_option do
--disable-winsock2_h) _winsock2_h=no ;;
--enable-smb) _smb=yes ;;
--disable-smb) _smb=no ;;
+ --enable-libquvi) _libquvi=yes ;;
+ --disable-libquvi) _libquvi=no ;;
--enable-joystick) _joystick=yes ;;
--disable-joystick) _joystick=no ;;
--enable-xvid) _xvid=yes ;;
@@ -3464,6 +3468,19 @@ else
fi
echores "$_smb"
+echocheck "libquvi support"
+if test "$_libquvi" = auto ; then
+ _libquvi=no
+ if pkg_config_add libquvi ; then
+ _libquvi=yes
+ fi
+fi
+if test "$_libquvi" = yes; then
+ def_libquvi="#define CONFIG_LIBQUVI 1"
+else
+ def_libquvi="#undef CONFIG_LIBQUVI"
+fi
+echores "$_libquvi"
#########
# VIDEO #
@@ -5718,6 +5735,7 @@ LCMS2 = $_lcms2
LIBNUT = $_libnut
LIBPOSTPROC = $libpostproc
LIBSMBCLIENT = $_smb
+LIBQUVI = $_libquvi
LIBTHEORA = $_theora
LIRC = $_lirc
LIVE555 = $_live
@@ -6046,6 +6064,7 @@ $def_live
$def_nemesi
$def_networking
$def_smb
+$def_libquvi
$def_socklen_t
$def_vstream
diff --git a/options.h b/options.h
index e77384b7f4..eacbafb89a 100644
--- a/options.h
+++ b/options.h
@@ -79,6 +79,7 @@ typedef struct MPOpts {
char **audio_lang;
char **sub_lang;
int hr_mp3_seek;
+ char *quvi_format;
char *audio_stream;
int audio_stream_cache;
diff --git a/stream/open.c b/stream/open.c
index ce0a415ceb..91e9ae2956 100644
--- a/stream/open.c
+++ b/stream/open.c
@@ -26,12 +26,14 @@
#include "config.h"
#include "mp_msg.h"
+#include "talloc.h"
#ifdef __FreeBSD__
#include <sys/cdrio.h>
#endif
#include "m_option.h"
+#include "options.h"
#include "stream.h"
#include "libmpdemux/demuxer.h"
@@ -42,6 +44,62 @@ char* cdrom_device=NULL;
char* dvd_device=NULL;
int dvd_title=0;
+#ifdef CONFIG_LIBQUVI
+
+#include <quvi/quvi.h>
+
+static const char *resolve_quvi(const char *url, struct MPOpts *opts)
+{
+ char *media_title, *media_url;
+ quvi_media_t m;
+ QUVIcode rc;
+ quvi_t q;
+
+ rc = quvi_init(&q);
+ if (rc != QUVI_OK)
+ return NULL;
+
+ // 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;
+ }
+
+ mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Checking URL...\n");
+
+ // 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");
+
+ rc = quvi_parse(q, (char *)url, &m);
+ if (rc != QUVI_OK) {
+ mp_msg(MSGT_OPEN, MSGL_ERR, "[quvi] %s\n", quvi_strerror(q, rc));
+ quvi_close(&q);
+ return NULL;
+ }
+
+ quvi_getprop(m, QUVIPROP_PAGETITLE, &media_title);
+ quvi_getprop(m, QUVIPROP_MEDIAURL, &media_url);
+
+ mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Site media title: '%s'\n",
+ media_title);
+ media_url = talloc_strdup(NULL, media_url);
+
+ quvi_parse_close(&m);
+ quvi_close(&q);
+
+ return media_url;
+}
+#endif
+
// Open a new stream (stdin/file/vcd/url)
stream_t* open_stream(const char *filename, struct MPOpts *options,
@@ -59,7 +117,16 @@ if(!filename) {
return NULL;
}
-//============ Open STDIN or plain FILE ============
+ const char *resolved = NULL;
+
+#ifdef CONFIG_LIBQUVI
+ resolved = resolve_quvi(filename, options);
+#endif
+
+ if (resolved)
+ filename = resolved;
- return open_stream_full(filename,STREAM_READ,options,file_format);
+ stream_t *res = open_stream_full(filename,STREAM_READ,options,file_format);
+ talloc_free((void *)resolved);
+ return res;
}