diff --git a/DOCS/edl-mpv.rst b/DOCS/edl-mpv.rst index 78da44a8bf..0e4d2b410e 100644 --- a/DOCS/edl-mpv.rst +++ b/DOCS/edl-mpv.rst @@ -239,6 +239,26 @@ title. The subtitle stream will use ``ducks`` as title. The ``track_meta`` header is not part of the core EDL format. It may be changed or removed at any time, depending on mpv's internal requirements. +Global metadata +=============== + +The special ``global_tags`` header can set metadata fields (aka tags) of the EDL +file. This metadata is supposed to be informational, much like for example ID3 +tags in audio files. Due to lack of separation of different kinds of metadata it +is unspecified what names are allowed, how they are interpreted, and whether +some of them affect playback functionally. (Much of this is unfortunately +inherited from FFmpeg. Another consequence of this is that FFmpeg "normalized" +tags are recognized, or stuff like replaygain tags.) + +Example:: + + !global_tags,title=bla,something_arbitrary=even_more_arbitrary + +Any parameter names are allowed. Repeated use of this adds to the tag list. If +``!new_stream`` is used, the location doesn't matter. + +May possibly be ignored in some cases, such as delayed media opening. + Delayed media opening ===================== diff --git a/demux/demux_edl.c b/demux/demux_edl.c index 256b304f3a..356b7eefb5 100644 --- a/demux/demux_edl.c +++ b/demux/demux_edl.c @@ -32,6 +32,7 @@ #include "options/path.h" #include "misc/bstr.h" #include "common/common.h" +#include "common/tags.h" #include "stream/stream.h" #define HEADER "# mpv EDL v0\n" @@ -60,6 +61,7 @@ struct tl_parts { struct tl_root { struct tl_parts **pars; int num_pars; + struct mp_tags *tags; }; struct priv { @@ -171,6 +173,7 @@ static struct sh_stream *get_meta(struct tl_parts *tl, int index) static struct tl_root *parse_edl(bstr str, struct mp_log *log) { struct tl_root *root = talloc_zero(NULL, struct tl_root); + root->tags = talloc_zero(root, struct mp_tags); struct tl_parts *tl = add_part(root); while (str.len) { if (bstr_eatstart0(&str, "#")) { @@ -273,6 +276,12 @@ static struct tl_root *parse_edl(bstr str, struct mp_log *log) sh->codec->fps = get_param_int(&ctx, "fps", 0); sh->codec->samplerate = get_param_int(&ctx, "samplerate", 0); tl->delay_open = true; + } else if (bstr_equals0(f_type, "global_tags")) { + for (int n = 0; n < ctx.num_params; n++) { + mp_tags_set_bstr(root->tags, ctx.param_names[n], + ctx.param_vals[n]); + } + ctx.num_params = 0; } else { mp_err(log, "Unknown header: '%.*s'\n", BSTR_P(f_type)); goto error; @@ -389,6 +398,7 @@ static void resolve_timestamps(struct tl_part *part, struct demuxer *demuxer) } static struct timeline_par *build_timeline(struct timeline *root, + struct tl_root *edl_root, struct tl_parts *parts) { struct timeline_par *tl = talloc_zero(root, struct timeline_par); @@ -542,6 +552,11 @@ static struct timeline_par *build_timeline(struct timeline *root, if (!root->meta) root->meta = tl->track_layout; + // Not very sane, since demuxer fields are supposed to be treated read-only + // from outside, but happens to work in this case, so who cares. + if (root->meta) + mp_tags_merge(root->meta->metadata, edl_root->tags); + assert(tl->num_parts == parts->num_parts); return tl; @@ -581,7 +596,7 @@ static void build_mpv_edl_timeline(struct timeline *tl) for (int n = 0; n < root->num_pars; n++) { struct tl_parts *parts = root->pars[n]; fix_filenames(parts, tl->demuxer->filename); - struct timeline_par *par = build_timeline(tl, parts); + struct timeline_par *par = build_timeline(tl, root, parts); if (!par) break; all_dash &= par->dash;