mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-19 19:42:24 +02:00
edl: add a way to add tags
Add new header which shows up as tags/metadata (associated with --display-tags). The way this is added means it doesn't always work, because root->meta (see code) can be NULL for some absurd reason. But it works for the one case I intended to use it (ytdl_hook, see next commit), though only in default configurations.
This commit is contained in:
parent
ea89e813f7
commit
adcf51dccd
@ -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
|
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.
|
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
|
Delayed media opening
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "options/path.h"
|
#include "options/path.h"
|
||||||
#include "misc/bstr.h"
|
#include "misc/bstr.h"
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
#include "common/tags.h"
|
||||||
#include "stream/stream.h"
|
#include "stream/stream.h"
|
||||||
|
|
||||||
#define HEADER "# mpv EDL v0\n"
|
#define HEADER "# mpv EDL v0\n"
|
||||||
@ -60,6 +61,7 @@ struct tl_parts {
|
|||||||
struct tl_root {
|
struct tl_root {
|
||||||
struct tl_parts **pars;
|
struct tl_parts **pars;
|
||||||
int num_pars;
|
int num_pars;
|
||||||
|
struct mp_tags *tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct priv {
|
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)
|
static struct tl_root *parse_edl(bstr str, struct mp_log *log)
|
||||||
{
|
{
|
||||||
struct tl_root *root = talloc_zero(NULL, struct tl_root);
|
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);
|
struct tl_parts *tl = add_part(root);
|
||||||
while (str.len) {
|
while (str.len) {
|
||||||
if (bstr_eatstart0(&str, "#")) {
|
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->fps = get_param_int(&ctx, "fps", 0);
|
||||||
sh->codec->samplerate = get_param_int(&ctx, "samplerate", 0);
|
sh->codec->samplerate = get_param_int(&ctx, "samplerate", 0);
|
||||||
tl->delay_open = true;
|
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 {
|
} else {
|
||||||
mp_err(log, "Unknown header: '%.*s'\n", BSTR_P(f_type));
|
mp_err(log, "Unknown header: '%.*s'\n", BSTR_P(f_type));
|
||||||
goto error;
|
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,
|
static struct timeline_par *build_timeline(struct timeline *root,
|
||||||
|
struct tl_root *edl_root,
|
||||||
struct tl_parts *parts)
|
struct tl_parts *parts)
|
||||||
{
|
{
|
||||||
struct timeline_par *tl = talloc_zero(root, struct timeline_par);
|
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)
|
if (!root->meta)
|
||||||
root->meta = tl->track_layout;
|
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);
|
assert(tl->num_parts == parts->num_parts);
|
||||||
return tl;
|
return tl;
|
||||||
|
|
||||||
@ -581,7 +596,7 @@ static void build_mpv_edl_timeline(struct timeline *tl)
|
|||||||
for (int n = 0; n < root->num_pars; n++) {
|
for (int n = 0; n < root->num_pars; n++) {
|
||||||
struct tl_parts *parts = root->pars[n];
|
struct tl_parts *parts = root->pars[n];
|
||||||
fix_filenames(parts, tl->demuxer->filename);
|
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)
|
if (!par)
|
||||||
break;
|
break;
|
||||||
all_dash &= par->dash;
|
all_dash &= par->dash;
|
||||||
|
Loading…
Reference in New Issue
Block a user