mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-19 19:42:24 +02:00
command: add sub-start & sub-end properties
These properties contain the current subtitle's start and end times. Can be useful to cut sample audio through the scripting interface.
This commit is contained in:
parent
0f938b197a
commit
cb32ad68f3
@ -1916,6 +1916,17 @@ Property list
|
||||
|
||||
This property is experimental and might be removed in the future.
|
||||
|
||||
``sub-start``
|
||||
Return the current subtitle start time (in seconds). If there's multiple
|
||||
current subtitles, returns the first start time. If no current subtitle is
|
||||
present null is returned instead.
|
||||
|
||||
``sub-end``
|
||||
Return the current subtitle start time (in seconds). If there's multiple
|
||||
current subtitles, return the last end time. If no current subtitle is
|
||||
present, or if it's present but has unknown or incorrect duration, null
|
||||
is returned instead.
|
||||
|
||||
``playlist-pos`` (RW)
|
||||
Current position on playlist. The first entry is on position 0. Writing
|
||||
to the property will restart playback at the written entry.
|
||||
|
@ -2845,6 +2845,38 @@ static int mp_property_sub_text(void *ctx, struct m_property *prop,
|
||||
return m_property_strdup_ro(action, arg, text);
|
||||
}
|
||||
|
||||
static struct sd_times get_times(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
{
|
||||
struct sd_times res = { .start = MP_NOPTS_VALUE, .end = MP_NOPTS_VALUE };
|
||||
MPContext *mpctx = ctx;
|
||||
struct track *track = mpctx->current_track[0][STREAM_SUB];
|
||||
struct dec_sub *sub = track ? track->d_sub : NULL;
|
||||
double pts = mpctx->playback_pts;
|
||||
if (!sub || pts == MP_NOPTS_VALUE)
|
||||
return res;
|
||||
return sub_get_times(sub, pts);
|
||||
}
|
||||
|
||||
static int mp_property_sub_start(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
{
|
||||
double start = get_times(ctx, prop, action, arg).start;
|
||||
if (start == MP_NOPTS_VALUE)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
return m_property_double_ro(action, arg, start);
|
||||
}
|
||||
|
||||
|
||||
static int mp_property_sub_end(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
{
|
||||
double end = get_times(ctx, prop, action, arg).end;
|
||||
if (end == MP_NOPTS_VALUE)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
return m_property_double_ro(action, arg, end);
|
||||
}
|
||||
|
||||
static int mp_property_cursor_autohide(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
{
|
||||
@ -3548,6 +3580,8 @@ static const struct m_property mp_properties_base[] = {
|
||||
{"sub-speed", mp_property_sub_speed},
|
||||
{"sub-pos", mp_property_sub_pos},
|
||||
{"sub-text", mp_property_sub_text},
|
||||
{"sub-start", mp_property_sub_start},
|
||||
{"sub-end", mp_property_sub_end},
|
||||
|
||||
{"vf", mp_property_vf},
|
||||
{"af", mp_property_af},
|
||||
|
@ -372,6 +372,23 @@ char *sub_get_text(struct dec_sub *sub, double pts)
|
||||
return text;
|
||||
}
|
||||
|
||||
struct sd_times sub_get_times(struct dec_sub *sub, double pts)
|
||||
{
|
||||
pthread_mutex_lock(&sub->lock);
|
||||
struct sd_times res = { .start = MP_NOPTS_VALUE, .end = MP_NOPTS_VALUE };
|
||||
|
||||
pts = pts_to_subtitle(sub, pts);
|
||||
|
||||
sub->last_vo_pts = pts;
|
||||
update_segment(sub);
|
||||
|
||||
if (sub->sd->driver->get_times)
|
||||
res = sub->sd->driver->get_times(sub->sd, pts);
|
||||
|
||||
pthread_mutex_unlock(&sub->lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void sub_reset(struct dec_sub *sub)
|
||||
{
|
||||
pthread_mutex_lock(&sub->lock);
|
||||
|
@ -21,6 +21,11 @@ enum sd_ctrl {
|
||||
SD_CTRL_SET_VIDEO_DEF_FPS,
|
||||
};
|
||||
|
||||
struct sd_times {
|
||||
double start;
|
||||
double end;
|
||||
};
|
||||
|
||||
struct attachment_list {
|
||||
struct demux_attachment *entries;
|
||||
int num_entries;
|
||||
@ -38,6 +43,7 @@ bool sub_read_packets(struct dec_sub *sub, double video_pts);
|
||||
void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, int format,
|
||||
double pts, struct sub_bitmaps *res);
|
||||
char *sub_get_text(struct dec_sub *sub, double pts);
|
||||
struct sd_times sub_get_times(struct dec_sub *sub, double pts);
|
||||
void sub_reset(struct dec_sub *sub);
|
||||
void sub_select(struct dec_sub *sub, bool selected);
|
||||
void sub_update_opts(struct dec_sub *sub);
|
||||
|
1
sub/sd.h
1
sub/sd.h
@ -40,6 +40,7 @@ struct sd_functions {
|
||||
void (*get_bitmaps)(struct sd *sd, struct mp_osd_res dim, int format,
|
||||
double pts, struct sub_bitmaps *res);
|
||||
char *(*get_text)(struct sd *sd, double pts);
|
||||
struct sd_times (*get_times)(struct sd *sd, double pts);
|
||||
};
|
||||
|
||||
struct lavc_conv;
|
||||
|
30
sub/sd_ass.c
30
sub/sd_ass.c
@ -593,6 +593,35 @@ static char *get_text(struct sd *sd, double pts)
|
||||
return ctx->last_text;
|
||||
}
|
||||
|
||||
static struct sd_times get_times(struct sd *sd, double pts)
|
||||
{
|
||||
struct sd_ass_priv *ctx = sd->priv;
|
||||
ASS_Track *track = ctx->ass_track;
|
||||
struct sd_times res = { .start = MP_NOPTS_VALUE, .end = MP_NOPTS_VALUE };
|
||||
|
||||
if (pts == MP_NOPTS_VALUE || ctx->duration_unknown)
|
||||
return res;
|
||||
|
||||
long long ipts = find_timestamp(sd, pts);
|
||||
|
||||
for (int i = 0; i < track->n_events; ++i) {
|
||||
ASS_Event *event = track->events + i;
|
||||
if (ipts >= event->Start && ipts < event->Start + event->Duration) {
|
||||
double start = event->Start / 1000.0;
|
||||
double end = event->Duration == UNKNOWN_DURATION ?
|
||||
MP_NOPTS_VALUE : (event->Start + event->Duration) / 1000.0;
|
||||
|
||||
if (res.start == MP_NOPTS_VALUE || res.start > start)
|
||||
res.start = start;
|
||||
|
||||
if (res.end == MP_NOPTS_VALUE || res.end < end)
|
||||
res.end = end;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void fill_plaintext(struct sd *sd, double pts)
|
||||
{
|
||||
struct sd_ass_priv *ctx = sd->priv;
|
||||
@ -687,6 +716,7 @@ const struct sd_functions sd_ass = {
|
||||
.decode = decode,
|
||||
.get_bitmaps = get_bitmaps,
|
||||
.get_text = get_text,
|
||||
.get_times = get_times,
|
||||
.control = control,
|
||||
.reset = reset,
|
||||
.select = enable_output,
|
||||
|
@ -383,14 +383,8 @@ static void decode(struct sd *sd, struct demux_packet *packet)
|
||||
}
|
||||
}
|
||||
|
||||
static void get_bitmaps(struct sd *sd, struct mp_osd_res d, int format,
|
||||
double pts, struct sub_bitmaps *res)
|
||||
static struct sub *get_current(struct sd_lavc_priv *priv, double pts)
|
||||
{
|
||||
struct sd_lavc_priv *priv = sd->priv;
|
||||
struct mp_subtitle_opts *opts = sd->opts;
|
||||
|
||||
priv->current_pts = pts;
|
||||
|
||||
struct sub *current = NULL;
|
||||
for (int n = 0; n < MAX_QUEUE; n++) {
|
||||
struct sub *sub = &priv->subs[n];
|
||||
@ -407,6 +401,19 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, int format,
|
||||
break;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
static void get_bitmaps(struct sd *sd, struct mp_osd_res d, int format,
|
||||
double pts, struct sub_bitmaps *res)
|
||||
{
|
||||
struct sd_lavc_priv *priv = sd->priv;
|
||||
struct mp_subtitle_opts *opts = sd->opts;
|
||||
|
||||
priv->current_pts = pts;
|
||||
|
||||
struct sub *current = get_current(priv, pts);
|
||||
|
||||
if (!current)
|
||||
return;
|
||||
|
||||
@ -483,6 +490,25 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, int format,
|
||||
|
||||
}
|
||||
|
||||
static struct sd_times get_times(struct sd *sd, double pts)
|
||||
{
|
||||
struct sd_lavc_priv *priv = sd->priv;
|
||||
struct sd_times res = { .start = MP_NOPTS_VALUE, .end = MP_NOPTS_VALUE };
|
||||
|
||||
if (pts == MP_NOPTS_VALUE)
|
||||
return res;
|
||||
|
||||
struct sub *current = get_current(priv, pts);
|
||||
|
||||
if (!current)
|
||||
return res;
|
||||
|
||||
res.start = current->pts;
|
||||
res.end = current->endpts;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool accepts_packet(struct sd *sd, double min_pts)
|
||||
{
|
||||
struct sd_lavc_priv *priv = sd->priv;
|
||||
@ -622,6 +648,7 @@ const struct sd_functions sd_lavc = {
|
||||
.init = init,
|
||||
.decode = decode,
|
||||
.get_bitmaps = get_bitmaps,
|
||||
.get_times = get_times,
|
||||
.accepts_packet = accepts_packet,
|
||||
.control = control,
|
||||
.reset = reset,
|
||||
|
7
test/subtimes.js
Normal file
7
test/subtimes.js
Normal file
@ -0,0 +1,7 @@
|
||||
function subtimes() {
|
||||
mp.msg.info("sub-start: " + mp.get_property_number("sub-start"));
|
||||
mp.msg.info("sub-end: " + mp.get_property_number("sub-end"));
|
||||
mp.msg.info("sub-text: " + mp.get_property_native("sub-text"));
|
||||
}
|
||||
|
||||
mp.add_key_binding("t", "subtimes", subtimes);
|
Loading…
Reference in New Issue
Block a user