mirror of
https://github.com/mpv-player/mpv
synced 2025-02-23 00:06:56 +00:00
core: show quvi page title in window title, clean up libquvi handling
Clean up handling of libquvi (which resolves URLs of streaming sites into URLs to the actual media playable by mpv). Move the code out of open.c to quvi.c, and invoke it explicitly from mplayer.c, instead of trying to resolve every filename passed to open_stream(). This allows easily passing metadata from the quvi context to the frontend. Expose QUVIPROP_PAGETITLE as "media-title" property, and use that instead of "filename" for the mplayer window title. (For YouTube, this is the video title.) It's cleaner too. Handle a potential reliability issue: check quvi_getprop return values. Since open.c contains barely anything but the open_stream() stub, move that to stream.c and delete open.c.
This commit is contained in:
parent
9dfcd3e9a2
commit
a19f197cb1
@ -237,7 +237,9 @@ loop x see ``--loop``
|
||||
speed x see ``--speed``
|
||||
filename currently played file (path stripped)
|
||||
path currently played file (full path)
|
||||
media-title filename or libquvi QUVIPROP_PAGETITLE
|
||||
demuxer
|
||||
stream-path filename (full path) of stream layer filename
|
||||
stream-pos x byte position in source stream
|
||||
stream-start start byte offset in source stream
|
||||
stream-end end position in bytes in source stream
|
||||
|
2
Makefile
2
Makefile
@ -204,7 +204,6 @@ SRCS_COMMON = asxparser.c \
|
||||
osdep/io.c \
|
||||
osdep/$(GETCH) \
|
||||
osdep/$(TIMER) \
|
||||
stream/open.c \
|
||||
stream/stream.c \
|
||||
stream/stream_ffmpeg.c \
|
||||
stream/stream_file.c \
|
||||
@ -242,6 +241,7 @@ SRCS_MPLAYER-$(GL_X11) += libvo/x11_common.c
|
||||
|
||||
SRCS_MPLAYER-$(JACK) += libao2/ao_jack.c
|
||||
SRCS_MPLAYER-$(JOYSTICK) += input/joystick.c
|
||||
SRCS_MPLAYER-$(LIBQUVI) += quvi.c
|
||||
SRCS_MPLAYER-$(LIRC) += input/lirc.c
|
||||
SRCS_MPLAYER-$(OPENAL) += libao2/ao_openal.c
|
||||
SRCS_MPLAYER-$(OSS) += libao2/ao_oss.c
|
||||
|
34
command.c
34
command.c
@ -162,6 +162,8 @@ static int mp_property_playback_speed(m_option_t *prop, int action,
|
||||
static int mp_property_path(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
if (!mpctx->filename)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (action == M_PROPERTY_GET) {
|
||||
*(char **)arg = talloc_strdup(NULL, mpctx->filename);
|
||||
return M_PROPERTY_OK;
|
||||
@ -169,6 +171,34 @@ static int mp_property_path(m_option_t *prop, int action, void *arg,
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int mp_property_media_title(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
char *name = mpctx->filename;
|
||||
if (mpctx->resolve_result)
|
||||
name = mpctx->resolve_result->title;
|
||||
if (!name)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (action == M_PROPERTY_GET) {
|
||||
*(char **)arg = talloc_strdup(NULL, name);
|
||||
return M_PROPERTY_OK;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int mp_property_stream_path(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
{
|
||||
struct stream *stream = mpctx->stream;
|
||||
if (!stream || !stream->url)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
if (action == M_PROPERTY_GET) {
|
||||
*(char **)arg = talloc_strdup(NULL, stream->url);
|
||||
return M_PROPERTY_OK;
|
||||
}
|
||||
return M_PROPERTY_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/// filename without path (RO)
|
||||
static int mp_property_filename(m_option_t *prop, int action, void *arg,
|
||||
MPContext *mpctx)
|
||||
@ -1364,6 +1394,10 @@ static const m_option_t mp_properties[] = {
|
||||
0, 0, 0, NULL },
|
||||
{ "path", mp_property_path, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "media-title", mp_property_media_title, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "stream-path", mp_property_stream_path, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "demuxer", mp_property_demuxer, CONF_TYPE_STRING,
|
||||
0, 0, 0, NULL },
|
||||
{ "stream-pos", mp_property_stream_pos, CONF_TYPE_INT64,
|
||||
|
@ -14,7 +14,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
|
||||
.softvol = SOFTVOL_AUTO,
|
||||
.softvol_max = 200,
|
||||
.ao_buffersize = -1,
|
||||
.vo_wintitle = "mpv - ${filename}",
|
||||
.vo_wintitle = "mpv - ${media-title}",
|
||||
.monitor_pixel_aspect = 1.0,
|
||||
.vo_panscanrange = 1.0,
|
||||
.cursor_autohide_delay = 1000,
|
||||
|
@ -140,6 +140,7 @@ typedef struct MPContext {
|
||||
int osd_function;
|
||||
struct playlist *playlist;
|
||||
char *filename; // currently playing file
|
||||
struct mp_resolve_result *resolve_result;
|
||||
enum stop_play_reason stop_play;
|
||||
unsigned int initialized_flags; // which subsystems have been initialized
|
||||
|
||||
|
22
mplayer.c
22
mplayer.c
@ -3668,6 +3668,16 @@ static void add_subtitle_fonts_from_sources(struct MPContext *mpctx)
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct mp_resolve_result *resolve_url(const char *filename,
|
||||
struct MPOpts *opts)
|
||||
{
|
||||
#ifdef CONFIG_LIBQUVI
|
||||
return mp_resolve_quvi(filename, opts);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Waiting for the slave master to send us a new file to play.
|
||||
static void idle_loop(struct MPContext *mpctx)
|
||||
{
|
||||
@ -3691,8 +3701,9 @@ static void play_current_file(struct MPContext *mpctx)
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
|
||||
mpctx->stop_play = 0;
|
||||
|
||||
mpctx->filename = NULL;
|
||||
mpctx->file_format = DEMUXER_TYPE_UNKNOWN;
|
||||
|
||||
if (mpctx->playlist->current)
|
||||
mpctx->filename = mpctx->playlist->current->filename;
|
||||
|
||||
@ -3761,7 +3772,11 @@ static void play_current_file(struct MPContext *mpctx)
|
||||
assert(mpctx->sh_video == NULL);
|
||||
assert(mpctx->sh_sub == NULL);
|
||||
|
||||
mpctx->stream = open_stream(mpctx->filename, opts, &mpctx->file_format);
|
||||
char *stream_filename = mpctx->filename;
|
||||
mpctx->resolve_result = resolve_url(stream_filename, opts);
|
||||
if (mpctx->resolve_result)
|
||||
stream_filename = mpctx->resolve_result->url;
|
||||
mpctx->stream = open_stream(stream_filename, opts, &mpctx->file_format);
|
||||
if (!mpctx->stream) { // error...
|
||||
libmpdemux_was_interrupted(mpctx);
|
||||
goto terminate_playback;
|
||||
@ -4032,6 +4047,9 @@ terminate_playback: // don't jump here after ao/vo/getch initialization!
|
||||
uninit_player(mpctx, uninitialize_parts);
|
||||
|
||||
mpctx->filename = NULL;
|
||||
mpctx->file_format = DEMUXER_TYPE_UNKNOWN;
|
||||
talloc_free(mpctx->resolve_result);
|
||||
mpctx->resolve_result = NULL;
|
||||
|
||||
vo_sub = NULL;
|
||||
#ifdef CONFIG_ASS
|
||||
|
@ -34,8 +34,16 @@ extern double force_fps;
|
||||
extern int vobsub_id;
|
||||
|
||||
struct MPContext;
|
||||
struct MPOpts;
|
||||
struct subtitle;
|
||||
|
||||
void set_osd_subtitle(struct MPContext *mpctx, struct subtitle *subs);
|
||||
|
||||
struct mp_resolve_result {
|
||||
char *url;
|
||||
char *title;
|
||||
};
|
||||
|
||||
struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts);
|
||||
|
||||
#endif /* MPLAYER_MPLAYER_H */
|
||||
|
@ -1,60 +1,33 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* with mpv; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/// We keep these 2 for the gui atm, but they will be removed.
|
||||
int vcd_track=0;
|
||||
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;
|
||||
#include "talloc.h"
|
||||
#include "mp_msg.h"
|
||||
#include "options.h"
|
||||
#include "mplayer.h"
|
||||
|
||||
struct mp_resolve_result *mp_resolve_quvi(const char *url, struct MPOpts *opts)
|
||||
{
|
||||
QUVIcode rc;
|
||||
|
||||
quvi_t q;
|
||||
rc = quvi_init(&q);
|
||||
if (rc != QUVI_OK)
|
||||
return NULL;
|
||||
@ -79,6 +52,7 @@ static const char *resolve_quvi(const char *url, struct MPOpts *opts)
|
||||
quvi_setopt(q, QUVIOPT_FORMAT, opts->quvi_format
|
||||
? opts->quvi_format : "best");
|
||||
|
||||
quvi_media_t m;
|
||||
rc = quvi_parse(q, (char *)url, &m);
|
||||
if (rc != QUVI_OK) {
|
||||
mp_msg(MSGT_OPEN, MSGL_ERR, "[quvi] %s\n", quvi_strerror(q, rc));
|
||||
@ -86,47 +60,24 @@ static const char *resolve_quvi(const char *url, struct MPOpts *opts)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
quvi_getprop(m, QUVIPROP_PAGETITLE, &media_title);
|
||||
quvi_getprop(m, QUVIPROP_MEDIAURL, &media_url);
|
||||
struct mp_resolve_result *result
|
||||
= talloc_zero(NULL, struct mp_resolve_result);
|
||||
|
||||
mp_msg(MSGT_OPEN, MSGL_INFO, "[quvi] Site media title: '%s'\n",
|
||||
media_title);
|
||||
media_url = talloc_strdup(NULL, media_url);
|
||||
char *val;
|
||||
|
||||
if (quvi_getprop(m, QUVIPROP_MEDIAURL, &val) == QUVI_OK)
|
||||
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);
|
||||
|
||||
return media_url;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Open a new stream (stdin/file/vcd/url)
|
||||
|
||||
stream_t* open_stream(const char *filename, struct MPOpts *options,
|
||||
int *file_format)
|
||||
{
|
||||
if (!file_format)
|
||||
file_format = &(int){DEMUXER_TYPE_UNKNOWN};
|
||||
// Check if playlist or unknown
|
||||
if (*file_format != DEMUXER_TYPE_PLAYLIST){
|
||||
*file_format=DEMUXER_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if(!filename) {
|
||||
mp_msg(MSGT_OPEN,MSGL_ERR,"NULL filename, report this bug\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *resolved = NULL;
|
||||
|
||||
#ifdef CONFIG_LIBQUVI
|
||||
resolved = resolve_quvi(filename, options);
|
||||
#endif
|
||||
|
||||
if (resolved)
|
||||
filename = resolved;
|
||||
|
||||
stream_t *res = open_stream_full(filename,STREAM_READ,options,file_format);
|
||||
talloc_free((void *)resolved);
|
||||
return res;
|
||||
if (!result->url) {
|
||||
talloc_free(result);
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -53,6 +53,12 @@
|
||||
|
||||
#include "cache2.h"
|
||||
|
||||
/// We keep these 2 for the gui atm, but they will be removed.
|
||||
int vcd_track=0;
|
||||
char* cdrom_device=NULL;
|
||||
char* dvd_device=NULL;
|
||||
int dvd_title=0;
|
||||
|
||||
struct input_ctx;
|
||||
static int (*stream_check_interrupt_cb)(struct input_ctx *ctx, int time);
|
||||
static struct input_ctx *stream_check_interrupt_ctx;
|
||||
@ -199,6 +205,12 @@ stream_t *open_stream_full(const char *filename, int mode,
|
||||
stream_t* s;
|
||||
char *redirected_url = NULL;
|
||||
|
||||
int dummy;
|
||||
if (!file_format)
|
||||
file_format = &dummy;
|
||||
|
||||
*file_format = DEMUXER_TYPE_UNKNOWN;
|
||||
|
||||
for(i = 0 ; auto_open_streams[i] ; i++) {
|
||||
sinfo = auto_open_streams[i];
|
||||
if(!sinfo->protocols) {
|
||||
@ -235,6 +247,18 @@ stream_t *open_stream_full(const char *filename, int mode,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream_t* open_stream(const char *filename, struct MPOpts *options,
|
||||
int *file_format)
|
||||
{
|
||||
|
||||
if(!filename) {
|
||||
mp_msg(MSGT_OPEN,MSGL_ERR,"NULL filename, report this bug\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return open_stream_full(filename,STREAM_READ,options,file_format);
|
||||
}
|
||||
|
||||
stream_t *open_output_stream(const char *filename, struct MPOpts *options)
|
||||
{
|
||||
int file_format; //unused
|
||||
|
Loading…
Reference in New Issue
Block a user