command: add metadata sub-property for track-list

Requires a little bit of massaging for the key/value access to work
correctly, it's not terribly intrusive all things considered.
This commit is contained in:
Dudemanguy
2025-01-27 20:16:50 -06:00
parent 5c3262628e
commit 814316fb2a
4 changed files with 44 additions and 1 deletions

View File

@@ -0,0 +1 @@
add `metadata` sub-property for `track-list`

View File

@@ -3373,6 +3373,10 @@ Property list
Dolby Vision profile and level. May not be available if the container
does not provide this information.
``track-list/N/metadata``,
Works like the ``metadata`` property, but it accesses metadata that is
set per track/stream instead of global values for the entire file.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
the following contents:
@@ -3426,6 +3430,8 @@ Property list
"replaygain-album-gain" MPV_FORMAT_DOUBLE
"dolby-vision-profile" MPV_FORMAT_INT64
"dolby-vision-level" MPV_FORMAT_INT64
"metadata" MPV_FORMAT_NODE_MAP
(key and string value for each metadata entry)
``current-tracks/...``
This gives access to currently selected tracks. It redirects to the correct

View File

@@ -220,6 +220,8 @@ struct m_sub_property {
.type = {.type = CONF_TYPE_BOOL}, .value = {.bool_ = (f)}
#define SUB_PROP_PTS(f) \
.type = {.type = &m_option_type_time}, .value = {.double_ = (f)}
#define SUB_PROP_KEYVALUE_LIST(l) \
.type = {.type = &m_option_type_keyvalue_list}, .value = {.keyvalue_list = (l)}
int m_property_read_sub_validate(void *ctx, struct m_property *prop,
int action, void *arg);

View File

@@ -2004,6 +2004,13 @@ static int get_track_entry(int item, int action, void *arg, void *ctx)
struct replaygain_data rg = has_rg ? *track->stream->codec->replaygain_data
: (struct replaygain_data){0};
struct mp_tags *tags = track->stream ? track->stream->tags : &(struct mp_tags){0};
char **tag_list = talloc_zero_array(NULL, char *, tags->num_keys * 2 + 1);
for (int i = 0; i < tags->num_keys; i++) {
tag_list[2 * i] = talloc_strdup(tag_list, tags->keys[i]);
tag_list[2 * i + 1] = talloc_strdup(tag_list, tags->values[i]);
}
double par = 0.0;
if (p.par_h)
par = p.par_w / (double) p.par_h;
@@ -2087,10 +2094,37 @@ static int get_track_entry(int item, int action, void *arg, void *ctx)
.unavailable = !p.dovi},
{"dolby-vision-level", SUB_PROP_INT(p.dv_level),
.unavailable = !p.dovi},
{"metadata", SUB_PROP_KEYVALUE_LIST(tag_list),
.unavailable = !tags->num_keys},
{0}
};
return m_property_read_sub(props, action, arg);
int ret = 0;
switch (action) {
case M_PROPERTY_KEY_ACTION: ;
struct m_property_action_arg *ka = arg;
if (!strncmp(ka->key, "metadata/", 9)) {
bstr key = {0};
char *rem = "";
m_property_split_path(ka->key, &key, &rem);
ka->key = !rem[0] ? "metadata" : rem;
if (rem[0]) {
if (!tags || tags->num_keys == 0) {
ret = M_PROPERTY_UNAVAILABLE;
} else {
ret = tag_property(action, (void *)ka, tags);
}
goto done;
}
}
MP_FALLTHROUGH;
default:
ret = m_property_read_sub(props, action, arg);
}
done:
talloc_free(tag_list);
return ret;
}
static const char *track_type_name(struct track *t)