diff options
-rw-r--r-- | DOCS/man/en/input.rst | 1 | ||||
-rw-r--r-- | demux/demux.c | 19 | ||||
-rw-r--r-- | demux/demux.h | 6 | ||||
-rw-r--r-- | demux/demux_lavf.c | 7 | ||||
-rw-r--r-- | demux/demux_mkv.c | 19 | ||||
-rw-r--r-- | mpvcore/command.c | 17 |
6 files changed, 59 insertions, 10 deletions
diff --git a/DOCS/man/en/input.rst b/DOCS/man/en/input.rst index bacb99c14b..c05fb664de 100644 --- a/DOCS/man/en/input.rst +++ b/DOCS/man/en/input.rst @@ -412,6 +412,7 @@ Name W Comment ``angle`` x current DVD angle ``metadata`` metadata key/value pairs ``metadata/<key>`` value of metadata entry ``<key>`` +``chapter-metadata`` metadata of current chapter (works similar) ``pause`` x pause status (bool) ``cache`` network cache fill state (0-100) ``pts-association-mode`` x see ``--pts-association-mode`` diff --git a/demux/demux.c b/demux/demux.c index 8d84d4450c..c3635b9ab1 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -870,18 +870,33 @@ void demuxer_sort_chapters(demuxer_t *demuxer) } int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name, - uint64_t start, uint64_t end) + uint64_t start, uint64_t end, uint64_t demuxer_id) { struct demux_chapter new = { .original_index = demuxer->num_chapters, .start = start, .end = end, .name = name.len ? bstrdup0(demuxer, name) : NULL, + .metadata = talloc_zero(demuxer, struct mp_tags), + .demuxer_id = demuxer_id, }; + mp_tags_set_bstr(new.metadata, bstr0("title"), name); MP_TARRAY_APPEND(demuxer, demuxer->chapters, demuxer->num_chapters, new); return 0; } +void demuxer_add_chapter_info(struct demuxer *demuxer, uint64_t demuxer_id, + bstr key, bstr value) +{ + for (int n = 0; n < demuxer->num_chapters; n++) { + struct demux_chapter *ch = &demuxer->chapters[n]; + if (ch->demuxer_id == demuxer_id) { + mp_tags_set_bstr(ch->metadata, key, value); + return; + } + } +} + static void add_stream_chapters(struct demuxer *demuxer) { if (demuxer->num_chapters) @@ -892,7 +907,7 @@ static void add_stream_chapters(struct demuxer *demuxer) if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p) != STREAM_OK) return; - demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0); + demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0); } } diff --git a/demux/demux.h b/demux/demux.h index 00758ea012..c42c964fa9 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -122,6 +122,8 @@ typedef struct demux_chapter int original_index; uint64_t start, end; char *name; + struct mp_tags *metadata; + uint64_t demuxer_id; // for mapping to internal demuxer data structures } demux_chapter_t; struct matroska_data { @@ -253,7 +255,9 @@ void demuxer_help(void); int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name, struct bstr type, struct bstr data); int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name, - uint64_t start, uint64_t end); + uint64_t start, uint64_t end, uint64_t demuxer_id); +void demuxer_add_chapter_info(struct demuxer *demuxer, uint64_t demuxer_id, + bstr key, bstr value); int demuxer_seek_chapter(struct demuxer *demuxer, int chapter, double *seek_pts); void demuxer_sort_chapters(demuxer_t *demuxer); diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 908eb3c111..dbe16a76b9 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -627,7 +627,12 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) (AVRational){1, 1000000000}); t = av_dict_get(c->metadata, "title", NULL, 0); demuxer_add_chapter(demuxer, t ? bstr0(t->value) : bstr0(NULL), - start, end); + start, end, i); + AVDictionaryEntry *t = NULL; + while ((t = av_dict_get(c->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { + demuxer_add_chapter_info(demuxer, i, bstr0(t->key), + bstr0(t->value)); + } } add_new_streams(demuxer); diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index a391dde5a6..120bbbb93a 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -878,7 +878,8 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer) BSTR_P(name)); if (idx == selected_edition){ - demuxer_add_chapter(demuxer, name, chapter.start, chapter.end); + demuxer_add_chapter(demuxer, name, chapter.start, chapter.end, + ca->chapter_uid); if (editions[idx].edition_flag_ordered) { chapter.name = talloc_strndup(m_chapters, name.start, name.len); @@ -913,11 +914,21 @@ static int demux_mkv_read_tags(demuxer_t *demuxer) for (int i = 0; i < tags.n_tag; i++) { struct ebml_tag tag = tags.tag[i]; if (tag.targets.target_track_uid || tag.targets.target_edition_uid || - tag.targets.target_chapter_uid || tag.targets.target_attachment_uid) + tag.targets.target_attachment_uid) continue; - for (int j = 0; j < tag.n_simple_tag; j++) - demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name, tag.simple_tag[j].tag_string); + if (tag.targets.target_chapter_uid) { + for (int j = 0; j < tag.n_simple_tag; j++) { + demuxer_add_chapter_info(demuxer, tag.targets.target_chapter_uid, + tag.simple_tag[j].tag_name, + tag.simple_tag[j].tag_string); + } + } else { + for (int j = 0; j < tag.n_simple_tag; j++) { + demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name, + tag.simple_tag[j].tag_string); + } + } } talloc_free(parse_ctx.talloc_ctx); diff --git a/mpvcore/command.c b/mpvcore/command.c index d8642e40fa..d986ae1a64 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -694,6 +694,19 @@ static int mp_property_metadata(m_option_t *prop, int action, void *arg, return tag_property(prop, action, arg, demuxer->metadata); } +static int mp_property_chapter_metadata(m_option_t *prop, int action, void *arg, + MPContext *mpctx) +{ + struct demuxer *demuxer = mpctx->master_demuxer; + int chapter = get_current_chapter(mpctx); + if (!demuxer || chapter < 0) + return M_PROPERTY_UNAVAILABLE; + + assert(chapter < demuxer->num_chapters); + + return tag_property(prop, action, arg, demuxer->chapters[chapter].metadata); +} + static int mp_property_pause(m_option_t *prop, int action, void *arg, void *ctx) { @@ -1741,8 +1754,8 @@ static const m_option_t mp_properties[] = { 0, 0, 0, NULL }, { "editions", mp_property_editions, CONF_TYPE_INT }, { "angle", mp_property_angle, &m_option_type_dummy }, - { "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST, - 0, 0, 0, NULL }, + { "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST }, + { "chapter-metadata", mp_property_chapter_metadata, CONF_TYPE_STRING_LIST }, M_OPTION_PROPERTY_CUSTOM("pause", mp_property_pause), { "cache", mp_property_cache, CONF_TYPE_INT }, M_OPTION_PROPERTY("pts-association-mode"), |