mirror of https://github.com/mpv-player/mpv
Allow some options taking filenames to refer to mpv config dir
Add the mp_get_user_path() function, and make it expand special path prefixes. Use it for some things in mpv which take filenames (--input-config, --screenshot-template, opengl icc-profile suboption). This allows accessing files in the mpv config dir without hardcoding the config path by prefixing the path with ~~/. Details see manpage additions.
This commit is contained in:
parent
dcf9f77c58
commit
683d7e88e4
|
@ -285,6 +285,28 @@ It has the following format::
|
|||
|
||||
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
|
||||
|
||||
Paths
|
||||
-----
|
||||
|
||||
Some care must be taken when passing arbitrary paths and filenames to mpv. For
|
||||
example, paths starting with ``-`` will be interpreted as options. Likewise,
|
||||
if a path contains the sequence ``://``, the string before that might be
|
||||
interpreted as protocol prefix, even though ``://`` can be part of a legal
|
||||
UNIX path. To avoid problems with arbitrary paths, you should be sure that
|
||||
absolute paths passed to mpv start with ``/``, and relative paths with ``./``.
|
||||
|
||||
The name ``-`` itself is interpreted as stdin, and will cause mpv to disable
|
||||
console controls. (Which makes it suitable for playing data piped to stdin.)
|
||||
|
||||
For paths passed to suboptions, the situation is further complicated by the
|
||||
need to escape special characters. To work this around, the path can be
|
||||
additionally wrapped in the ``%n%string_of_length_n`` syntax (see above).
|
||||
|
||||
Some mpv options interpret paths starting with ``~``. Currently, the prefix
|
||||
``~~/`` expands to the mpv configuration directory (usually ``~/.mpv/``).
|
||||
``~/`` expands to the user's home directory. (The trailing ``/`` is always
|
||||
required.)
|
||||
|
||||
Per-File Options
|
||||
----------------
|
||||
|
||||
|
|
|
@ -2156,23 +2156,31 @@ static int parse_config(struct input_ctx *ictx, bool builtin, bstr data,
|
|||
|
||||
static int parse_config_file(struct input_ctx *ictx, char *file, bool warn)
|
||||
{
|
||||
int r = 0;
|
||||
void *tmp = talloc_new(NULL);
|
||||
stream_t *s = NULL;
|
||||
|
||||
file = mp_get_user_path(tmp, file);
|
||||
if (!mp_path_exists(file)) {
|
||||
MP_MSG(ictx, warn ? MSGL_ERR : MSGL_V,
|
||||
"Input config file %s not found.\n", file);
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
stream_t *s = stream_open(file, NULL);
|
||||
s = stream_open(file, NULL);
|
||||
if (!s) {
|
||||
MP_ERR(ictx, "Can't open input config file %s.\n", file);
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
bstr res = stream_read_complete(s, NULL, 1000000);
|
||||
free_stream(s);
|
||||
bstr data = stream_read_complete(s, tmp, 1000000);
|
||||
MP_VERBOSE(ictx, "Parsing input config file %s\n", file);
|
||||
int n_binds = parse_config(ictx, false, res, file, NULL);
|
||||
talloc_free(res.start);
|
||||
int n_binds = parse_config(ictx, false, data, file, NULL);
|
||||
MP_VERBOSE(ictx, "Input config file %s parsed: %d binds\n", file, n_binds);
|
||||
return 1;
|
||||
r = 1;
|
||||
|
||||
done:
|
||||
free_stream(s);
|
||||
talloc_free(tmp);
|
||||
return r;
|
||||
}
|
||||
|
||||
// If name is NULL, return "default".
|
||||
|
|
|
@ -97,6 +97,28 @@ char *mp_find_global_config_file(const char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
char *mp_get_user_path(void *talloc_ctx, const char *path)
|
||||
{
|
||||
if (!path)
|
||||
return NULL;
|
||||
bstr bpath = bstr0(path);
|
||||
if (bstr_eatstart0(&bpath, "~")) {
|
||||
// parse to "~" <prefix> "/" <rest>
|
||||
bstr prefix, rest;
|
||||
if (bstr_split_tok(bpath, "/", &prefix, &rest)) {
|
||||
const char *rest0 = rest.start; // ok in this case
|
||||
char *res = NULL;
|
||||
if (bstr_equals0(prefix, "~"))
|
||||
res = talloc_steal(talloc_ctx, mp_find_user_config_file(rest0));
|
||||
if (bstr_equals0(prefix, ""))
|
||||
res = mp_path_join(talloc_ctx, bstr0(getenv("HOME")), rest);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return talloc_strdup(talloc_ctx, path);
|
||||
}
|
||||
|
||||
char *mp_basename(const char *path)
|
||||
{
|
||||
char *s;
|
||||
|
|
|
@ -36,6 +36,11 @@ char *mp_find_global_config_file(const char *filename);
|
|||
// Search for the input filename in the user configuration location.
|
||||
char *mp_find_user_config_file(const char *filename);
|
||||
|
||||
// Normally returns a talloc_strdup'ed copy of the path, except for special
|
||||
// paths starting with '~'. Used to allow the user explicitly reference a
|
||||
// file from the user's home or mpv config directory.
|
||||
char *mp_get_user_path(void *talloc_ctx, const char *path);
|
||||
|
||||
// Return pointer to filename part of path
|
||||
|
||||
char *mp_basename(const char *path);
|
||||
|
|
|
@ -233,7 +233,10 @@ static char *create_fname(struct MPContext *mpctx, char *template,
|
|||
}
|
||||
|
||||
res = talloc_strdup_append(res, template);
|
||||
return talloc_asprintf_append(res, ".%s", file_ext);
|
||||
res = talloc_asprintf_append(res, ".%s", file_ext);
|
||||
char *fname = mp_get_user_path(NULL, res);
|
||||
talloc_free(res);
|
||||
return fname;
|
||||
|
||||
error_exit:
|
||||
talloc_free(res);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "mpvcore/bstr.h"
|
||||
#include "mpvcore/mp_msg.h"
|
||||
#include "mpvcore/m_option.h"
|
||||
#include "mpvcore/path.h"
|
||||
|
||||
#include "gl_video.h"
|
||||
#include "gl_lcms.h"
|
||||
|
@ -90,11 +91,13 @@ static void lcms2_error_handler(cmsContext ctx, cmsUInt32Number code,
|
|||
static struct bstr load_file(void *talloc_ctx, const char *filename)
|
||||
{
|
||||
struct bstr res = {0};
|
||||
stream_t *s = stream_open(filename, NULL);
|
||||
char *fname = mp_get_user_path(NULL, filename);
|
||||
stream_t *s = stream_open(fname, NULL);
|
||||
if (s) {
|
||||
res = stream_read_complete(s, talloc_ctx, 1000000000);
|
||||
free_stream(s);
|
||||
}
|
||||
talloc_free(fname);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue