How to retrieve the tag value from a file for scripting?

I would like to be able to retrieve a tag value that is already present in a file, and make it available for scripting.

As an example, a file may have the value ‘Eno • Hyde’ for albumartist.
If I want to keep that value, I can prevent Picard from clearing albumartist, or just choose not to retrieve and (over)write albumartist.

But, I do want to retrieve what MusicBrainz has to offer for albumartist.
In this case it could offer e.g.: “Eno / Hyde”, or “Brian Eno • Karl Hyde”, etc. etc.

So I want those too, but without them overwriting my existing albumartist value.
But as soon as I use a function to get ‘albumartist’, it will retrieve the data from MB, and ignore what is present in the file.

Trying to achieve this, I am guessing I would first need to $get the existing albumartist value from the file, put it in a placeholder for further processing, and then perform some $copymerge stuff.

But I can’t figure out how to do this?
(and I have an annoying itch that I am missing something very obvious here)

This is currently not possible. With scripting you don’t have access to file metadata. For one scripting gives you no way to access different metadata from different source (there is simply not syntax for this). But the main reason is because of the time when scripts are executed: Scripts are always run against metadata loaded from MusicBrainz, and exactly after the data gets loaded and before files get matched.

For the same reason accessing file metadata also mostly does not work with metadata processor plugins. Plugins also operate on data loaded from MB (either on album or track level). While plugins in theory have the power to access file objects, those objects in many cases are not yet attached to the albums and especially not the tracks.

You see from this that the main idea behind both plugins and scripts was to be able to modify data loaded from MusicBrainz and tailor it to your needs. But of course it would make sense to have both available at other parts. There are a couple of threads here and tickets in the issue tracker that suggest improvements in this area, but currently the above limits apply.

2 Likes

Maybe there is a way :smiley:

Try using the “keep” plugin with the following script the following (completely untested):

$set(mb_albumartist,%albumartist%)
$keep(albumartist)

This should remove the albumartist tag from the tags written (thus leaving it to the original value in the file) but make it available as %mb_albumartist% (or name that however you like).

You still don’t get access to the file metadata itself in the script, but for the use case you described that would not be necessary.

2 Likes

Thanks a lot for the explanation, and for this suggestion @outsidecontext .

I must admit that even after reading a bit about the $keep feature, I still do not understand what the plugin does exactly, and how it fits in between Picards own settings and scripts.
At the moment it sounds confusing to me: it will keep tags, and it will delete tags?

I’ll give it a try to find out if it’s useful for what I am trying to do here.

Something in between :smiley:

When setting or unsetting tests you usually mostly use $set() and $unset() . $set is straight forward, it will just set the tag to a given value. $unset() is the opposite, it will clear the tag. But clearing it just means it has an empty value now, it will still replace what was in the file.

$keep() on the other hands just removes the tag from the tags loaded from Picard as if it never even was there. Thus it is treated like any other tag which is in the file but for which there is no replacement from MusicBrainz. In this case the file data will be kept.

The next Picard version will provide an even different option: $delete(). This will mark a tag for complete removal from the file.

1 Like

Primal question:
Are the workings of the plugin influenced by Picards setting ‘clear all tags’?
I.e. if Picard is set not to clear all tags, will the plugin still delete all?

It implies to do so in the extremely sparse explanation: “Adds a $keep() function to delete all tags except the ones that you want.”

I’m sorry that your good explanations seem wasted on me.
I have now tried all sorts of settings and combinations, but I just can’t find a way to make this “$keep” work in any predictable manner.
I’m abandoning it before I kick the wall and hurt my toes.

(Or should I say unset the wall, clear my toes from not deleting pain. That sums up pretty well how confusing this plugin and its wordings are to me.)

I’m the author of the keep plugin. I wasn’t even aware it could be used for things like this :wink:

What the plugin is supposed to do is basically a mass-$unset: for each tag name in the list of tags Picard will save to the file, do the same as $unset(tag name), unless the tag name is in the list of tags passed to $keep¹.
The use case I wrote is for is if you want to only save a small subset of the tags Picard can write, so that the whitelist of tags is much smaller and easier to write than the large amounts of $unset calls required to unset most the tags. I suppose that if the tags are not cleared (by setting Clear all tags), this also has the side-effect of keeping the values of the tags not in the whitelist passed to $keep.

¹ It will also not unset tags important for Picard itself, like mentioned in the description.

1 Like

Thanks for responding @Mineo. (and for creating the plugin of course)

Together with the explanation from outsidecontext this should clear it up a bit for me.
(in case I give this a try again)

I hope you understand how confusing this all can be to users not too savvy with coding and/or not being very experienced with Picard.
For example I was taking the word ‘deleting’ (as it says in the description) too literal.
It now seems to me that it is more about ‘allowing’ and ‘excluding’.
(but that could probably be argued depending on perspective)