summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2019-09-21 20:11:18 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2019-09-22 09:19:45 +0200
commitcb32ad68f31de784a13ca5a2847143c4c37738ce (patch)
tree9d9d5497c9a58d54ae5ef7cb226e81dd5fb14cb7
parent0f938b197a79c09b01a9dcf39f02e95d9d7fb4a2 (diff)
downloadmpv-cb32ad68f31de784a13ca5a2847143c4c37738ce.tar.bz2
mpv-cb32ad68f31de784a13ca5a2847143c4c37738ce.tar.xz
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.
-rw-r--r--DOCS/man/input.rst11
-rw-r--r--player/command.c34
-rw-r--r--sub/dec_sub.c17
-rw-r--r--sub/dec_sub.h6
-rw-r--r--sub/sd.h1
-rw-r--r--sub/sd_ass.c30
-rw-r--r--sub/sd_lavc.c41
-rw-r--r--test/subtimes.js7
8 files changed, 140 insertions, 7 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 52be5540df..4aba60cd8b 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -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.
diff --git a/player/command.c b/player/command.c
index 6239a3fa95..7db7c44ae8 100644
--- a/player/command.c
+++ b/player/command.c
@@ -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},
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index a31cad77bc..27cab201d9 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -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);
diff --git a/sub/dec_sub.h b/sub/dec_sub.h
index 06d4a6127e..5449b97ad0 100644
--- a/sub/dec_sub.h
+++ b/sub/dec_sub.h
@@ -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);
diff --git a/sub/sd.h b/sub/sd.h
index 0c4dd3465b..6c3fc4e285 100644
--- a/sub/sd.h
+++ b/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;
diff --git a/sub/sd_ass.c b/sub/sd_ass.c
index 163ffb6648..18ef961e8c 100644
--- a/sub/sd_ass.c
+++ b/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,
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 4620c8bd9b..72c89913e0 100644
--- a/sub/sd_lavc.c
+++ b/sub/sd_lavc.c
@@ -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,
diff --git a/test/subtimes.js b/test/subtimes.js
new file mode 100644
index 0000000000..7821e0b5c0
--- /dev/null
+++ b/test/subtimes.js
@@ -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);