mirror of https://github.com/mpv-player/mpv
command: add sub_reload and sub_remove commands
sub_remove remove an external subtitle track, for whatever this may be needed. sub_reload removes and re-adds an external subtitle track. Also rename sub_load to sub_add, because that seems to be more in line with sub_remove.
This commit is contained in:
parent
dd7dc2ee3d
commit
b7052b431c
|
@ -158,10 +158,20 @@ run "<command>"
|
|||
quit [<code>]
|
||||
Exit the player using the given exit code.
|
||||
|
||||
sub_load "<file>"
|
||||
sub_add "<file>"
|
||||
Load the given subtitle file. It's not selected as current subtitle after
|
||||
loading.
|
||||
|
||||
sub_remove [<id>]
|
||||
Remove the given subtitle track. If the ``id`` argument is missing, remove
|
||||
the current track. (Works on external subtitle files only.)
|
||||
|
||||
sub_reload [<id>]
|
||||
Reload the given subtitle tracks. If the ``id`` argument is missing, remove
|
||||
the current track. (Works on external subtitle files only.)
|
||||
|
||||
This works by unloading and re-adding the subtitle track.
|
||||
|
||||
sub_step <skip>
|
||||
Change subtitle timing such, that the subtitle event after the next <skip>
|
||||
subtitle events is displayed. <skip> can be negative to step back.
|
||||
|
|
|
@ -2205,12 +2205,33 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||
break;
|
||||
#endif /* CONFIG_TV */
|
||||
|
||||
case MP_CMD_SUB_LOAD:
|
||||
case MP_CMD_SUB_ADD:
|
||||
if (sh_video) {
|
||||
add_subtitles(mpctx, cmd->args[0].v.s, sh_video->fps, 0);
|
||||
mp_add_subtitles(mpctx, cmd->args[0].v.s, sh_video->fps, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case MP_CMD_SUB_REMOVE: {
|
||||
struct track *sub = mp_track_by_tid(mpctx, STREAM_SUB, cmd->args[0].v.i);
|
||||
if (sub)
|
||||
mp_remove_track(mpctx, sub);
|
||||
break;
|
||||
}
|
||||
|
||||
case MP_CMD_SUB_RELOAD: {
|
||||
struct track *sub = mp_track_by_tid(mpctx, STREAM_SUB, cmd->args[0].v.i);
|
||||
if (sh_video && sub && sub->is_external && sub->external_filename)
|
||||
{
|
||||
struct track *nsub = mp_add_subtitles(mpctx, sub->external_filename,
|
||||
sh_video->fps, 0);
|
||||
if (nsub) {
|
||||
mp_remove_track(mpctx, sub);
|
||||
mp_switch_track(mpctx, nsub->type, nsub);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MP_CMD_SCREENSHOT:
|
||||
screenshot_request(mpctx, cmd->args[0].v.i, cmd->args[1].v.i);
|
||||
break;
|
||||
|
|
|
@ -144,7 +144,9 @@ static const mp_cmd_t mp_cmds[] = {
|
|||
{ MP_CMD_PRINT_TEXT, "print_text", { ARG_STRING } },
|
||||
{ MP_CMD_SHOW_TEXT, "show_text", { ARG_STRING, OARG_INT(-1), OARG_INT(0) } },
|
||||
{ MP_CMD_SHOW_PROGRESS, "show_progress", },
|
||||
{ MP_CMD_SUB_LOAD, "sub_load", { ARG_STRING } },
|
||||
{ MP_CMD_SUB_ADD, "sub_add", { ARG_STRING } },
|
||||
{ MP_CMD_SUB_REMOVE, "sub_remove", { OARG_INT(-1) } },
|
||||
{ MP_CMD_SUB_RELOAD, "sub_reload", { OARG_INT(-1) } },
|
||||
|
||||
{ MP_CMD_TV_START_SCAN, "tv_start_scan", },
|
||||
{ MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", { ARG_INT } },
|
||||
|
@ -231,6 +233,7 @@ static const struct legacy_cmd legacy_cmds[] = {
|
|||
{"saturation", "add saturation"},
|
||||
{"hue", "add hue"},
|
||||
{"switch_vsync", "cycle vsync"},
|
||||
{"sub_load", "sub_add"},
|
||||
{"sub_select", "cycle sub"},
|
||||
{"sub_pos", "add sub-pos"},
|
||||
{"sub_delay", "add sub-delay"},
|
||||
|
|
|
@ -47,7 +47,9 @@ enum mp_command_type {
|
|||
MP_CMD_FRAME_STEP,
|
||||
MP_CMD_SPEED_MULT,
|
||||
MP_CMD_RUN,
|
||||
MP_CMD_SUB_LOAD,
|
||||
MP_CMD_SUB_ADD,
|
||||
MP_CMD_SUB_REMOVE,
|
||||
MP_CMD_SUB_RELOAD,
|
||||
MP_CMD_KEYDOWN_EVENTS,
|
||||
MP_CMD_SET,
|
||||
MP_CMD_GET_PROPERTY,
|
||||
|
|
|
@ -100,6 +100,7 @@ struct track {
|
|||
|
||||
// If this track is from an external file (e.g. subtitle file).
|
||||
bool is_external;
|
||||
char *external_filename;
|
||||
|
||||
// If the track's stream changes with the timeline (ordered chapters).
|
||||
bool under_timeline;
|
||||
|
@ -274,7 +275,8 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask);
|
|||
void reinit_audio_chain(struct MPContext *mpctx);
|
||||
void init_vo_spudec(struct MPContext *mpctx);
|
||||
double playing_audio_pts(struct MPContext *mpctx);
|
||||
void add_subtitles(struct MPContext *mpctx, char *filename, float fps, int noerr);
|
||||
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
|
||||
float fps, int noerr);
|
||||
int reinit_video_chain(struct MPContext *mpctx);
|
||||
void pause_player(struct MPContext *mpctx);
|
||||
void unpause_player(struct MPContext *mpctx);
|
||||
|
@ -294,6 +296,7 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
|||
struct track *track);
|
||||
struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
|
||||
int tid);
|
||||
bool mp_remove_track(struct MPContext *mpctx, struct track *track);
|
||||
|
||||
// timeline/tl_matroska.c
|
||||
void build_ordered_chapter_timeline(struct MPContext *mpctx);
|
||||
|
|
|
@ -943,15 +943,15 @@ static void add_dvd_tracks(struct MPContext *mpctx)
|
|||
#endif
|
||||
}
|
||||
|
||||
void add_subtitles(struct MPContext *mpctx, char *filename, float fps,
|
||||
int noerr)
|
||||
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename,
|
||||
float fps, int noerr)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
sub_data *subd = NULL;
|
||||
struct sh_sub *sh = NULL;
|
||||
|
||||
if (filename == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if (opts->ass_enabled) {
|
||||
#ifdef CONFIG_ASS
|
||||
|
@ -976,7 +976,7 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps,
|
|||
if (!sh && !subd) {
|
||||
mp_tmsg(MSGT_CPLAYER, noerr ? MSGL_WARN : MSGL_ERR,
|
||||
"Cannot load subtitles: %s\n", filename);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct track *track = talloc_ptrtype(NULL, track);
|
||||
|
@ -988,8 +988,10 @@ void add_subtitles(struct MPContext *mpctx, char *filename, float fps,
|
|||
.is_external = true,
|
||||
.sh_sub = talloc_steal(track, sh),
|
||||
.subdata = talloc_steal(track, subd),
|
||||
.external_filename = talloc_strdup(track, filename),
|
||||
};
|
||||
MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
|
||||
return track;
|
||||
}
|
||||
|
||||
void init_vo_spudec(struct MPContext *mpctx)
|
||||
|
@ -1983,6 +1985,8 @@ void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
|||
struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
|
||||
int tid)
|
||||
{
|
||||
if (tid == -1)
|
||||
return mpctx->current_track[type];
|
||||
for (int n = 0; n < mpctx->num_tracks; n++) {
|
||||
struct track *track = mpctx->tracks[n];
|
||||
if (track->type == type && track->user_tid == tid)
|
||||
|
@ -1991,6 +1995,32 @@ struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool mp_remove_track(struct MPContext *mpctx, struct track *track)
|
||||
{
|
||||
if (track->under_timeline)
|
||||
return false;
|
||||
if (!track->is_external)
|
||||
return false;
|
||||
|
||||
if (mpctx->current_track[track->type] == track) {
|
||||
mp_switch_track(mpctx, track->type, NULL);
|
||||
if (mpctx->current_track[track->type] == track)
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
while (index < mpctx->num_tracks && mpctx->tracks[index] != track)
|
||||
index++;
|
||||
assert(index < mpctx->num_tracks);
|
||||
while (index + 1 < mpctx->num_tracks) {
|
||||
mpctx->tracks[index] = mpctx->tracks[index + 1];
|
||||
index++;
|
||||
}
|
||||
mpctx->num_tracks--;
|
||||
talloc_free(track);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Modify video timing to match the audio timeline. There are two main
|
||||
* reasons this is needed. First, video and audio can start from different
|
||||
* positions at beginning of file or after a seek (MPlayer starts both
|
||||
|
@ -3540,13 +3570,13 @@ static void open_subtitles_from_options(struct MPContext *mpctx)
|
|||
double sub_fps = mpctx->sh_video ? mpctx->sh_video->fps : 25;
|
||||
if (mpctx->opts.sub_name) {
|
||||
for (int i = 0; mpctx->opts.sub_name[i] != NULL; ++i)
|
||||
add_subtitles(mpctx, mpctx->opts.sub_name[i], sub_fps, 0);
|
||||
mp_add_subtitles(mpctx, mpctx->opts.sub_name[i], sub_fps, 0);
|
||||
}
|
||||
if (mpctx->opts.sub_auto) { // auto load sub file ...
|
||||
char **tmp = find_text_subtitles(&mpctx->opts, mpctx->filename);
|
||||
int nsub = MP_TALLOC_ELEMS(tmp);
|
||||
for (int i = 0; i < nsub; i++)
|
||||
add_subtitles(mpctx, tmp[i], sub_fps, 1);
|
||||
mp_add_subtitles(mpctx, tmp[i], sub_fps, 1);
|
||||
talloc_free(tmp);
|
||||
}
|
||||
}
|
||||
|
@ -3596,6 +3626,7 @@ static void open_external_file(struct MPContext *mpctx, char *filename,
|
|||
struct track *t = add_stream_track(mpctx, stream, false);
|
||||
t->is_external = true;
|
||||
t->title = talloc_strdup(t, filename);
|
||||
t->external_filename = talloc_strdup(t, filename);
|
||||
num_added++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue