mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 03:52:22 +02:00
player: add external audio file auto-loading
Apparently some people want this. Not enabled by default. Fixes #967.
This commit is contained in:
parent
cf8fa2bdd4
commit
c07e046bfa
@ -1039,6 +1039,16 @@ Audio
|
|||||||
maximum amplification, i.e. amplify by 200%. The default volume (no
|
maximum amplification, i.e. amplify by 200%. The default volume (no
|
||||||
change in volume) will be ``50`` in this case.
|
change in volume) will be ``50`` in this case.
|
||||||
|
|
||||||
|
``--audio-file-auto=<no|exact|fuzzy|all>``, ``--no-audio-file-auto``
|
||||||
|
Load additional audio files matching the video filename. The parameter
|
||||||
|
specifies how external audio files are matched. This is disabled by
|
||||||
|
default.
|
||||||
|
|
||||||
|
:no: Don't automatically load external audio files (default).
|
||||||
|
:exact: Load the media filename with audio file extension.
|
||||||
|
:fuzzy: Load all audio files containing media filename.
|
||||||
|
:all: Load all audio files in the current directory.
|
||||||
|
|
||||||
``--audio-client-name=<name>``
|
``--audio-client-name=<name>``
|
||||||
The application name the player reports to the audio API. Can be useful
|
The application name the player reports to the audio API. Can be useful
|
||||||
if you want to force a different audio profile (e.g. with PulseAudio),
|
if you want to force a different audio profile (e.g. with PulseAudio),
|
||||||
|
@ -328,6 +328,8 @@ const m_option_t mp_opts[] = {
|
|||||||
OPT_FLAG("sub-fix-timing", sub_fix_timing, 0),
|
OPT_FLAG("sub-fix-timing", sub_fix_timing, 0),
|
||||||
OPT_CHOICE("sub-auto", sub_auto, 0,
|
OPT_CHOICE("sub-auto", sub_auto, 0,
|
||||||
({"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})),
|
({"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})),
|
||||||
|
OPT_CHOICE("audio-file-auto", audiofile_auto, 0,
|
||||||
|
({"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})),
|
||||||
OPT_INTRANGE("sub-pos", sub_pos, 0, 0, 100),
|
OPT_INTRANGE("sub-pos", sub_pos, 0, 0, 100),
|
||||||
OPT_FLOATRANGE("sub-gauss", sub_gauss, 0, 0.0, 3.0),
|
OPT_FLOATRANGE("sub-gauss", sub_gauss, 0, 0.0, 3.0),
|
||||||
OPT_FLAG("sub-gray", sub_gray, 0),
|
OPT_FLAG("sub-gray", sub_gray, 0),
|
||||||
@ -764,6 +766,7 @@ const struct MPOpts mp_default_opts = {
|
|||||||
.movie_aspect = -1.,
|
.movie_aspect = -1.,
|
||||||
.field_dominance = -1,
|
.field_dominance = -1,
|
||||||
.sub_auto = 0,
|
.sub_auto = 0,
|
||||||
|
.audiofile_auto = -1,
|
||||||
.osd_bar_visible = 1,
|
.osd_bar_visible = 1,
|
||||||
#if HAVE_LIBASS
|
#if HAVE_LIBASS
|
||||||
.ass_enabled = 1,
|
.ass_enabled = 1,
|
||||||
|
@ -231,6 +231,7 @@ typedef struct MPOpts {
|
|||||||
char **sub_name;
|
char **sub_name;
|
||||||
char **sub_paths;
|
char **sub_paths;
|
||||||
int sub_auto;
|
int sub_auto;
|
||||||
|
int audiofile_auto;
|
||||||
int use_text_osd;
|
int use_text_osd;
|
||||||
int osd_bar_visible;
|
int osd_bar_visible;
|
||||||
float osd_bar_align_x;
|
float osd_bar_align_x;
|
||||||
|
@ -646,57 +646,32 @@ bool mp_remove_track(struct MPContext *mpctx, struct track *track)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void open_subtitles_from_options(struct MPContext *mpctx)
|
|
||||||
{
|
|
||||||
if (mpctx->opts->sub_name) {
|
|
||||||
for (int i = 0; mpctx->opts->sub_name[i] != NULL; ++i)
|
|
||||||
mp_add_subtitles(mpctx, mpctx->opts->sub_name[i]);
|
|
||||||
}
|
|
||||||
if (mpctx->opts->sub_auto >= 0) { // auto load sub file ...
|
|
||||||
void *tmp = talloc_new(NULL);
|
|
||||||
char *base_filename = mpctx->filename;
|
|
||||||
char *stream_filename = NULL;
|
|
||||||
if (mpctx->demuxer) {
|
|
||||||
if (demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_BASE_FILENAME,
|
|
||||||
&stream_filename) > 0)
|
|
||||||
base_filename = talloc_steal(tmp, stream_filename);
|
|
||||||
}
|
|
||||||
struct subfn *list = find_text_subtitles(mpctx->global, base_filename);
|
|
||||||
talloc_steal(tmp, list);
|
|
||||||
for (int i = 0; list && list[i].fname; i++) {
|
|
||||||
char *filename = list[i].fname;
|
|
||||||
char *lang = list[i].lang;
|
|
||||||
for (int n = 0; n < mpctx->num_sources; n++) {
|
|
||||||
if (strcmp(mpctx->sources[n]->stream->url, filename) == 0)
|
|
||||||
goto skip;
|
|
||||||
}
|
|
||||||
struct track *track = mp_add_subtitles(mpctx, filename);
|
|
||||||
if (track) {
|
|
||||||
track->auto_loaded = true;
|
|
||||||
if (!track->lang)
|
|
||||||
track->lang = talloc_strdup(track, lang);
|
|
||||||
}
|
|
||||||
skip:;
|
|
||||||
}
|
|
||||||
talloc_free(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct track *open_external_file(struct MPContext *mpctx, char *filename,
|
static struct track *open_external_file(struct MPContext *mpctx, char *filename,
|
||||||
char *demuxer_name,
|
|
||||||
enum stream_type filter)
|
enum stream_type filter)
|
||||||
{
|
{
|
||||||
struct MPOpts *opts = mpctx->opts;
|
struct MPOpts *opts = mpctx->opts;
|
||||||
if (!filename)
|
if (!filename)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
char *disp_filename = filename;
|
char *disp_filename = filename;
|
||||||
if (strncmp(disp_filename, "memory://", 9) == 0)
|
if (strncmp(disp_filename, "memory://", 9) == 0)
|
||||||
disp_filename = "memory://"; // avoid noise
|
disp_filename = "memory://"; // avoid noise
|
||||||
|
|
||||||
struct stream *stream = stream_open(filename, mpctx->global);
|
struct stream *stream = stream_open(filename, mpctx->global);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
if (filter != STREAM_SUB)
|
|
||||||
|
char *demuxer_name = NULL;
|
||||||
|
switch (filter) {
|
||||||
|
case STREAM_SUB:
|
||||||
|
demuxer_name = opts->sub_demuxer_name;
|
||||||
|
break;
|
||||||
|
case STREAM_AUDIO:
|
||||||
|
demuxer_name = opts->audio_demuxer_name;
|
||||||
stream_enable_cache(&stream, &opts->stream_cache);
|
stream_enable_cache(&stream, &opts->stream_cache);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
struct demuxer_params params = {
|
struct demuxer_params params = {
|
||||||
.expect_subtitle = filter == STREAM_SUB,
|
.expect_subtitle = filter == STREAM_SUB,
|
||||||
};
|
};
|
||||||
@ -706,6 +681,7 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename,
|
|||||||
free_stream(stream);
|
free_stream(stream);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct track *first = NULL;
|
struct track *first = NULL;
|
||||||
for (int n = 0; n < demuxer->num_streams; n++) {
|
for (int n = 0; n < demuxer->num_streams; n++) {
|
||||||
struct sh_stream *sh = demuxer->streams[n];
|
struct sh_stream *sh = demuxer->streams[n];
|
||||||
@ -724,6 +700,7 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename,
|
|||||||
disp_filename);
|
disp_filename);
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, demuxer);
|
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, demuxer);
|
||||||
return first;
|
return first;
|
||||||
|
|
||||||
@ -736,17 +713,53 @@ err_out:
|
|||||||
static void open_audiofiles_from_options(struct MPContext *mpctx)
|
static void open_audiofiles_from_options(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
struct MPOpts *opts = mpctx->opts;
|
struct MPOpts *opts = mpctx->opts;
|
||||||
for (int n = 0; opts->audio_files && opts->audio_files[n]; n++) {
|
for (int n = 0; opts->audio_files && opts->audio_files[n]; n++)
|
||||||
open_external_file(mpctx, opts->audio_files[n], opts->audio_demuxer_name,
|
open_external_file(mpctx, opts->audio_files[n], STREAM_AUDIO);
|
||||||
STREAM_AUDIO);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename)
|
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename)
|
||||||
|
{
|
||||||
|
return open_external_file(mpctx, filename, STREAM_SUB);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_subtitles_from_options(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
struct MPOpts *opts = mpctx->opts;
|
struct MPOpts *opts = mpctx->opts;
|
||||||
return open_external_file(mpctx, filename, opts->sub_demuxer_name,
|
for (int i = 0; opts->sub_name && opts->sub_name[i] != NULL; i++)
|
||||||
STREAM_SUB);
|
mp_add_subtitles(mpctx, opts->sub_name[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void autoload_external_files(struct MPContext *mpctx)
|
||||||
|
{
|
||||||
|
if (mpctx->opts->sub_auto < 0 && mpctx->opts->audiofile_auto < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
void *tmp = talloc_new(NULL);
|
||||||
|
char *base_filename = mpctx->filename;
|
||||||
|
char *stream_filename = NULL;
|
||||||
|
if (mpctx->demuxer) {
|
||||||
|
if (demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_BASE_FILENAME,
|
||||||
|
&stream_filename) > 0)
|
||||||
|
base_filename = talloc_steal(tmp, stream_filename);
|
||||||
|
}
|
||||||
|
struct subfn *list = find_external_files(mpctx->global, base_filename);
|
||||||
|
talloc_steal(tmp, list);
|
||||||
|
for (int i = 0; list && list[i].fname; i++) {
|
||||||
|
char *filename = list[i].fname;
|
||||||
|
char *lang = list[i].lang;
|
||||||
|
for (int n = 0; n < mpctx->num_sources; n++) {
|
||||||
|
if (strcmp(mpctx->sources[n]->stream->url, filename) == 0)
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
struct track *track = open_external_file(mpctx, filename, list[i].type);
|
||||||
|
if (track) {
|
||||||
|
track->auto_loaded = true;
|
||||||
|
if (!track->lang)
|
||||||
|
track->lang = talloc_strdup(track, lang);
|
||||||
|
}
|
||||||
|
skip:;
|
||||||
|
}
|
||||||
|
talloc_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do stuff to a newly loaded playlist. This includes any processing that may
|
// Do stuff to a newly loaded playlist. This includes any processing that may
|
||||||
@ -1086,6 +1099,7 @@ goto_reopen_demuxer: ;
|
|||||||
|
|
||||||
open_subtitles_from_options(mpctx);
|
open_subtitles_from_options(mpctx);
|
||||||
open_audiofiles_from_options(mpctx);
|
open_audiofiles_from_options(mpctx);
|
||||||
|
autoload_external_files(mpctx);
|
||||||
|
|
||||||
check_previous_track_selection(mpctx);
|
check_previous_track_selection(mpctx);
|
||||||
|
|
||||||
|
@ -18,15 +18,27 @@ static const char *const sub_exts[] = {"utf", "utf8", "utf-8", "idx", "sub", "sr
|
|||||||
"smi", "rt", "txt", "ssa", "aqt", "jss",
|
"smi", "rt", "txt", "ssa", "aqt", "jss",
|
||||||
"js", "ass", "mks", NULL};
|
"js", "ass", "mks", NULL};
|
||||||
|
|
||||||
static bool is_sub_ext(bstr ext)
|
static const char *const audio_exts[] = {"mp3", "aac", "mka", "dts", "flac",
|
||||||
|
"ogg", "m4a", NULL};
|
||||||
|
|
||||||
|
static bool test_ext_list(bstr ext, const char *const *list)
|
||||||
{
|
{
|
||||||
for (int n = 0; sub_exts[n]; n++) {
|
for (int n = 0; list[n]; n++) {
|
||||||
if (bstrcasecmp(bstr0(sub_exts[n]), ext) == 0)
|
if (bstrcasecmp(bstr0(list[n]), ext) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_ext(bstr ext)
|
||||||
|
{
|
||||||
|
if (test_ext_list(ext, sub_exts))
|
||||||
|
return STREAM_SUB;
|
||||||
|
if (test_ext_list(ext, audio_exts))
|
||||||
|
return STREAM_AUDIO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static struct bstr strip_ext(struct bstr str)
|
static struct bstr strip_ext(struct bstr str)
|
||||||
{
|
{
|
||||||
int dotpos = bstrrchr(str, '.');
|
int dotpos = bstrrchr(str, '.');
|
||||||
@ -45,7 +57,7 @@ static struct bstr get_ext(struct bstr s)
|
|||||||
|
|
||||||
bool mp_might_be_subtitle_file(const char *filename)
|
bool mp_might_be_subtitle_file(const char *filename)
|
||||||
{
|
{
|
||||||
return is_sub_ext(get_ext(bstr0(filename)));
|
return test_ext(get_ext(bstr0(filename))) == STREAM_SUB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare_sub_filename(const void *a, const void *b)
|
static int compare_sub_filename(const void *a, const void *b)
|
||||||
@ -87,15 +99,6 @@ static struct bstr guess_lang_from_filename(struct bstr name)
|
|||||||
return (struct bstr){name.start + i + 1, n};
|
return (struct bstr){name.start + i + 1, n};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Append all the subtitles in the given path matching fname
|
|
||||||
* @param opts MPlayer options
|
|
||||||
* @param slist pointer to the subtitles list tallocated
|
|
||||||
* @param nsub pointer to the number of subtitles
|
|
||||||
* @param path Look for subtitles in this directory
|
|
||||||
* @param fname Subtitle filename (pattern)
|
|
||||||
* @param limit_fuzziness Ignore flag when sub_fuziness == 2
|
|
||||||
*/
|
|
||||||
static void append_dir_subtitles(struct mpv_global *global,
|
static void append_dir_subtitles(struct mpv_global *global,
|
||||||
struct subfn **slist, int *nsub,
|
struct subfn **slist, int *nsub,
|
||||||
struct bstr path, const char *fname,
|
struct bstr path, const char *fname,
|
||||||
@ -103,7 +106,7 @@ static void append_dir_subtitles(struct mpv_global *global,
|
|||||||
{
|
{
|
||||||
void *tmpmem = talloc_new(NULL);
|
void *tmpmem = talloc_new(NULL);
|
||||||
struct MPOpts *opts = global->opts;
|
struct MPOpts *opts = global->opts;
|
||||||
struct mp_log *log = mp_log_new(tmpmem, global->log, "find_subfiles");
|
struct mp_log *log = mp_log_new(tmpmem, global->log, "find_files");
|
||||||
|
|
||||||
if (mp_is_url(bstr0(fname)))
|
if (mp_is_url(bstr0(fname)))
|
||||||
goto out;
|
goto out;
|
||||||
@ -121,7 +124,7 @@ static void append_dir_subtitles(struct mpv_global *global,
|
|||||||
DIR *d = opendir(path0);
|
DIR *d = opendir(path0);
|
||||||
if (!d)
|
if (!d)
|
||||||
goto out;
|
goto out;
|
||||||
mp_verbose(log, "Load subtitles in %.*s\n", BSTR_P(path));
|
mp_verbose(log, "Loading external files in %.*s\n", BSTR_P(path));
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
while ((de = readdir(d))) {
|
while ((de = readdir(d))) {
|
||||||
struct bstr dename = bstr0(de->d_name);
|
struct bstr dename = bstr0(de->d_name);
|
||||||
@ -133,21 +136,35 @@ static void append_dir_subtitles(struct mpv_global *global,
|
|||||||
struct bstr tmp_fname_ext = get_ext(dename);
|
struct bstr tmp_fname_ext = get_ext(dename);
|
||||||
struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext);
|
struct bstr tmp_fname_trim = bstr_strip(tmp_fname_noext);
|
||||||
|
|
||||||
// does it end with a subtitle extension?
|
// check what it is (most likely)
|
||||||
if (!is_sub_ext(tmp_fname_ext))
|
int type = test_ext(tmp_fname_ext);
|
||||||
|
char **langs = NULL;
|
||||||
|
int fuzz = -1;
|
||||||
|
switch (type) {
|
||||||
|
case STREAM_SUB:
|
||||||
|
langs = opts->sub_lang;
|
||||||
|
fuzz = opts->sub_auto;
|
||||||
|
break;
|
||||||
|
case STREAM_AUDIO:
|
||||||
|
langs = opts->audio_lang;
|
||||||
|
fuzz = opts->audiofile_auto;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fuzz < 0)
|
||||||
goto next_sub;
|
goto next_sub;
|
||||||
|
|
||||||
// we have a (likely) subtitle file
|
// we have a (likely) subtitle file
|
||||||
int prio = 0;
|
int prio = 0;
|
||||||
char *found_lang = NULL;
|
char *found_lang = NULL;
|
||||||
if (opts->sub_lang) {
|
if (langs) {
|
||||||
if (bstr_startswith(tmp_fname_trim, f_fname_trim)) {
|
if (bstr_startswith(tmp_fname_trim, f_fname_trim)) {
|
||||||
struct bstr lang = guess_lang_from_filename(tmp_fname_trim);
|
struct bstr lang = guess_lang_from_filename(tmp_fname_trim);
|
||||||
if (lang.len) {
|
if (lang.len) {
|
||||||
for (int n = 0; opts->sub_lang[n]; n++) {
|
for (int n = 0; langs[n]; n++) {
|
||||||
if (bstr_startswith0(lang, opts->sub_lang[n])) {
|
if (bstr_startswith0(lang, langs[n])) {
|
||||||
prio = 4; // matches the movie name + lang extension
|
prio = 4; // matches the movie name + lang extension
|
||||||
found_lang = opts->sub_lang[n];
|
found_lang = langs[n];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,18 +173,19 @@ static void append_dir_subtitles(struct mpv_global *global,
|
|||||||
}
|
}
|
||||||
if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0)
|
if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0)
|
||||||
prio = 3; // matches the movie name
|
prio = 3; // matches the movie name
|
||||||
if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0
|
if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && fuzz >= 1)
|
||||||
&& opts->sub_auto >= 1)
|
|
||||||
prio = 2; // contains the movie name
|
prio = 2; // contains the movie name
|
||||||
if (!prio) {
|
if (!prio) {
|
||||||
// doesn't contain the movie name
|
// doesn't contain the movie name
|
||||||
// don't try in the mplayer subtitle directory
|
// don't try in the mplayer subtitle directory
|
||||||
if (!limit_fuzziness && opts->sub_auto >= 2) {
|
if (!limit_fuzziness && fuzz >= 2) {
|
||||||
prio = 1;
|
prio = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_dbg(log, "Potential sub file: \"%s\" Priority: %d\n", de->d_name, prio);
|
mp_dbg(log, "Potential external file: \"%s\" Priority: %d\n",
|
||||||
|
de->d_name, prio);
|
||||||
|
|
||||||
if (prio) {
|
if (prio) {
|
||||||
prio += prio;
|
prio += prio;
|
||||||
char *subpath = mp_path_join(*slist, path, dename);
|
char *subpath = mp_path_join(*slist, path, dename);
|
||||||
@ -179,6 +197,7 @@ static void append_dir_subtitles(struct mpv_global *global,
|
|||||||
if (strncmp(subpath, "./", 2) == 0)
|
if (strncmp(subpath, "./", 2) == 0)
|
||||||
subpath += 2;
|
subpath += 2;
|
||||||
|
|
||||||
|
sub->type = type;
|
||||||
sub->priority = prio;
|
sub->priority = prio;
|
||||||
sub->fname = subpath;
|
sub->fname = subpath;
|
||||||
sub->lang = found_lang;
|
sub->lang = found_lang;
|
||||||
@ -222,9 +241,9 @@ static void filter_subidx(struct subfn **slist, int *nsub)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a list of subtitles found, sorted by priority.
|
// Return a list of subtitles and audio files found, sorted by priority.
|
||||||
// Last element is terminated with a fname==NULL entry.
|
// Last element is terminated with a fname==NULL entry.
|
||||||
struct subfn *find_text_subtitles(struct mpv_global *global, const char *fname)
|
struct subfn *find_external_files(struct mpv_global *global, const char *fname)
|
||||||
{
|
{
|
||||||
struct MPOpts *opts = global->opts;
|
struct MPOpts *opts = global->opts;
|
||||||
struct subfn *slist = talloc_array_ptrtype(NULL, slist, 1);
|
struct subfn *slist = talloc_array_ptrtype(NULL, slist, 1);
|
||||||
@ -233,20 +252,22 @@ struct subfn *find_text_subtitles(struct mpv_global *global, const char *fname)
|
|||||||
// Load subtitles from current media directory
|
// Load subtitles from current media directory
|
||||||
append_dir_subtitles(global, &slist, &n, mp_dirname(fname), fname, 0);
|
append_dir_subtitles(global, &slist, &n, mp_dirname(fname), fname, 0);
|
||||||
|
|
||||||
// Load subtitles in dirs specified by sub-paths option
|
if (opts->sub_auto >= 0) {
|
||||||
if (opts->sub_paths) {
|
// Load subtitles in dirs specified by sub-paths option
|
||||||
for (int i = 0; opts->sub_paths[i]; i++) {
|
if (opts->sub_paths) {
|
||||||
char *path = mp_path_join(slist, mp_dirname(fname),
|
for (int i = 0; opts->sub_paths[i]; i++) {
|
||||||
bstr0(opts->sub_paths[i]));
|
char *path = mp_path_join(slist, mp_dirname(fname),
|
||||||
append_dir_subtitles(global, &slist, &n, bstr0(path), fname, 0);
|
bstr0(opts->sub_paths[i]));
|
||||||
|
append_dir_subtitles(global, &slist, &n, bstr0(path), fname, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Load subtitles in ~/.mpv/sub limiting sub fuzziness
|
// Load subtitles in ~/.mpv/sub limiting sub fuzziness
|
||||||
char *mp_subdir = mp_find_config_file(NULL, global, "sub/");
|
char *mp_subdir = mp_find_config_file(NULL, global, "sub/");
|
||||||
if (mp_subdir)
|
if (mp_subdir)
|
||||||
append_dir_subtitles(global, &slist, &n, bstr0(mp_subdir), fname, 1);
|
append_dir_subtitles(global, &slist, &n, bstr0(mp_subdir), fname, 1);
|
||||||
talloc_free(mp_subdir);
|
talloc_free(mp_subdir);
|
||||||
|
}
|
||||||
|
|
||||||
// Sort by name for filter_subidx()
|
// Sort by name for filter_subidx()
|
||||||
qsort(slist, n, sizeof(*slist), compare_sub_filename);
|
qsort(slist, n, sizeof(*slist), compare_sub_filename);
|
||||||
|
@ -22,13 +22,14 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct subfn {
|
struct subfn {
|
||||||
|
int type; // STREAM_SUB/STREAM_AUDIO
|
||||||
int priority;
|
int priority;
|
||||||
char *fname;
|
char *fname;
|
||||||
char *lang;
|
char *lang;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpv_global;
|
struct mpv_global;
|
||||||
struct subfn *find_text_subtitles(struct mpv_global *global, const char *fname);
|
struct subfn *find_external_files(struct mpv_global *global, const char *fname);
|
||||||
|
|
||||||
bool mp_might_be_subtitle_file(const char *filename);
|
bool mp_might_be_subtitle_file(const char *filename);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user