player: strip 'file://' from filenames on playback start

This fixes two things:

1. Dropping files on the VO window will auto-load subtitles (since most
   drag & drop code prefixes the filenames with 'file://', and the
   subtitle auto-load code considers 'file://' non-local)
2. Fix behavior of the %x screenshot filename template (similar problem)

One could force all that code to special-case 'file://' URLs, but just
replacing the filename on playback start is simpler.
This commit is contained in:
wm4 2014-01-08 21:46:42 +01:00
parent 59c6fa2201
commit 1d2a111337
3 changed files with 34 additions and 13 deletions

View File

@ -1029,6 +1029,7 @@ static void load_per_file_options(m_config_t *conf,
static void play_current_file(struct MPContext *mpctx) static void play_current_file(struct MPContext *mpctx)
{ {
struct MPOpts *opts = mpctx->opts; struct MPOpts *opts = mpctx->opts;
void *tmp = talloc_new(NULL);
double playback_start = -1e100; double playback_start = -1e100;
mpctx->initialized_flags |= INITIALIZED_PLAYBACK; mpctx->initialized_flags |= INITIALIZED_PLAYBACK;
@ -1047,6 +1048,10 @@ static void play_current_file(struct MPContext *mpctx)
if (!mpctx->filename) if (!mpctx->filename)
goto terminate_playback; goto terminate_playback;
char *local_filename = mp_file_url_to_filename(tmp, bstr0(mpctx->filename));
if (local_filename)
mpctx->filename = local_filename;
#if HAVE_ENCODING #if HAVE_ENCODING
encode_lavc_discontinuity(mpctx->encode_lavc_ctx); encode_lavc_discontinuity(mpctx->encode_lavc_ctx);
#endif #endif
@ -1096,6 +1101,7 @@ static void play_current_file(struct MPContext *mpctx)
char *stream_filename = mpctx->filename; char *stream_filename = mpctx->filename;
mpctx->resolve_result = resolve_url(stream_filename, mpctx->global); mpctx->resolve_result = resolve_url(stream_filename, mpctx->global);
if (mpctx->resolve_result) { if (mpctx->resolve_result) {
talloc_steal(tmp, mpctx->resolve_result);
print_resolve_contents(mpctx->log, mpctx->resolve_result); print_resolve_contents(mpctx->log, mpctx->resolve_result);
if (mpctx->resolve_result->playlist) { if (mpctx->resolve_result->playlist) {
transfer_playlist(mpctx, mpctx->resolve_result->playlist); transfer_playlist(mpctx, mpctx->resolve_result->playlist);
@ -1370,8 +1376,8 @@ terminate_playback: // don't jump here after ao/vo/getch initialization!
getch2_enable(); getch2_enable();
mpctx->filename = NULL; mpctx->filename = NULL;
talloc_free(mpctx->resolve_result);
mpctx->resolve_result = NULL; mpctx->resolve_result = NULL;
talloc_free(tmp);
// Played/paused for longer than 3 seconds -> ok // Played/paused for longer than 3 seconds -> ok
bool playback_short = mpctx->stop_play == AT_END_OF_FILE && bool playback_short = mpctx->stop_play == AT_END_OF_FILE &&

View File

@ -281,4 +281,7 @@ typedef struct {
void mp_url_unescape_inplace(char *buf); void mp_url_unescape_inplace(char *buf);
char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok); char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok);
// stream_file.c
char *mp_file_url_to_filename(void *talloc_ctx, bstr url);
#endif /* MPLAYER_STREAM_H */ #endif /* MPLAYER_STREAM_H */

View File

@ -32,6 +32,7 @@
#include "common/msg.h" #include "common/msg.h"
#include "stream.h" #include "stream.h"
#include "options/m_option.h" #include "options/m_option.h"
#include "options/path.h"
struct priv { struct priv {
int fd; int fd;
@ -91,10 +92,25 @@ static void s_close(stream_t *s)
close(p->fd); close(p->fd);
} }
// If url is a file:// URL, return the local filename, otherwise return NULL.
char *mp_file_url_to_filename(void *talloc_ctx, bstr url)
{
bstr proto = mp_split_proto(url, &url);
if (bstrcasecmp0(proto, "file") != 0)
return NULL;
char *filename = bstrto0(talloc_ctx, url);
mp_url_unescape_inplace(filename);
#if HAVE_DOS_PATHS
// extract '/' from '/x:/path'
if (filename[0] == '/' && filename[1] && filename[2] == ':')
memmove(filename, filename + 1, strlen(filename)); // including \0
#endif
return filename;
}
static int open_f(stream_t *stream, int mode) static int open_f(stream_t *stream, int mode)
{ {
int fd; int fd;
char *filename = stream->path;
struct priv *priv = talloc_ptrtype(stream, priv); struct priv *priv = talloc_ptrtype(stream, priv);
*priv = (struct priv) { *priv = (struct priv) {
.fd = -1 .fd = -1
@ -111,15 +127,12 @@ static int open_f(stream_t *stream, int mode)
return STREAM_UNSUPPORTED; return STREAM_UNSUPPORTED;
} }
// "file://" prefix -> decode URL-style escapes char *filename = mp_file_url_to_filename(stream, bstr0(stream->url));
if (strlen(stream->url) > strlen(stream->path)) if (filename) {
mp_url_unescape_inplace(stream->path); stream->path = filename;
} else {
#if HAVE_DOS_PATHS filename = stream->path;
// extract '/' from '/x:/path' }
if (filename[0] == '/' && filename[1] && filename[2] == ':')
filename++;
#endif
if (!strcmp(filename, "-")) { if (!strcmp(filename, "-")) {
if (mode == STREAM_READ) { if (mode == STREAM_READ) {
@ -151,8 +164,7 @@ static int open_f(stream_t *stream, int mode)
#ifndef __MINGW32__ #ifndef __MINGW32__
struct stat st; struct stat st;
if (fstat(fd, &st) == 0 && S_ISDIR(st.st_mode)) { if (fstat(fd, &st) == 0 && S_ISDIR(st.st_mode)) {
MP_ERR(stream, "File is a directory: '%s'\n", MP_ERR(stream, "File is a directory: '%s'\n", filename);
filename);
close(fd); close(fd);
return STREAM_ERROR; return STREAM_ERROR;
} }