-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fetch artists, performers, engineers etc flexibly #3589
Conversation
Thanks for getting this started! This is pretty tricky… I think an important thing to focus on here is that this is a pretty specialized use case, and I'm not sure most users will want to have this enabled by default. We can consider it, under the hypothesis that extra tags may not bother anybody as long as they are not written to the file, but we may also want to consider creating some kind of new plugin hook that lets the MusicBrainz data extraction be extended. This way, users could customize the way MB data gets "flattened" into tags. I'm also uncertain about the idea of using a naming convention to do synchronization—i.e., to "reserve" all tags starting with Finally, I definitely think that beets field names should not contain spaces. Otherwise, it's pretty hard to write things like template strings that use the fields. |
A built-in list of fields is not a good idea in my opinion. That would require creating a field for every 200+ instrument of MB, the overwhelming majority of them empty, not even talking about all the credits (in opera, typically), and now that we have flexible tags why not use them? In #1547 (comment) I interpret it as reserving certain fields for a plugin and singling them out by a prefix seems the easiest way of doing so. |
I can't speak for everyone, but as far as I'm concerned, the use case would just be to use beets to check on the info on a recording, not to use them to name files. |
Hi! I changed the code a little. A few quality of life improvements: |
This also uses two additional optional arguments in |
What do you mean? The way it is now is that there is an additional argument in beets core that allows to choose whether one wants to get this additional data that is activated by a plugin, but that means changes in beets core. Do you have something else in mind? |
What I meant there is that we could add a brand-new event that allows plugins to process MusicBrainz responses and extract additional data. This would let the task of MusicBrainz-to-beets data extraction evolve independently of the beets core, which would remain somewhat minimal. If other people in the future come up with other swaths of additional data they'd like to fetch from MusicBrainz, we won't need to add new flags like |
Ah ok! Now I understand. I had a little thought at this, but I'm running into a problem: I can get the response of MB by setting up an event and process the response, but I somehow need the items linked to this response to apply the new tags to it. So I need both the MB response and the item, but those two are created in completely different parts of the code. |
For example, I tried to put up an event that gives the MB response:
Then I fetch the response in
Now I want to apply this info to the item it belongs to. How do we get it? I could create an event that triggers when an item is called, but there would be no guaranty that this would be the same item than the one we just got the MB data for. How do these triggers work btw? Does the whole program stop to process it when it triggers? Can |
It just turns into a normal function call, so yes, the rest of beets (in the current thread) "stops" while the event is handled. And yes, they can return values! 🎉 Here's an example from elsewhere in beets: Lines 865 to 866 in 31855a9
So a sensible thing to do here might be to just return a |
Thanks! With the end of the lockdown and the start of the final phase of my PhD, I won't be able to work on this too much in the next weeks, but I'm keeping an eye on it. |
When writing performer information to files, does this use the same tag mapping that is used by Picard? We shouldn't roll our own tags, because then support by media players will be nonexistent. Picard's tags do have some support, at least they are shown correctly by mpd/ncmpcpp. |
Thanks for the fix, but now I get this error:
|
@aereaux That is strange, I don't have this problem. Are you sure you use the latest version? |
However, one problem I do have, is that I need the |
Ah, looks like it's my fault. I have a plugin that was causing the issue. No idea why it's suddenly failing, though |
beets/autotag/mb.py
Outdated
@@ -270,8 +270,8 @@ def track_info(recording, index=None, medium=None, medium_index=None, | |||
info.arranger = u', '.join(arranger) | |||
|
|||
# Supplementary fields provided by plugins | |||
extra_trackdatas = plugins.send('mb_track_extract', data=recording) | |||
for extra_trackdata in extra_trackdatas: | |||
extra_trackdatasets = plugins.send('mb_track_extract', info=recording) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the parameter called data in the docs?
https://github.com/beetbox/beets/blame/master/docs/dev/plugins.rst#L255
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, sorry I screwed up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be fine now
I did a test, they are not fetched if mbsync is disabled, even if the 'performer_info' option is active. |
Does it work now, with your plugin? |
Yep, changing the parameter name back fixed it. Also, at least as a user, I think of mbsync as only updating the same information that is retrieved on initial import. It seems like it would make more sense either to have this in core so that it gets retrieved on initial import and on mbsync (probably behind a feature flag) or to put it in a separate plugin like how parentwork works, although parentwork does do a lot of additional info fetching. |
Actually, it is retrieved at the initial import if mbsync and the 'performer_info' option are active. That's probably the feature flag you're looking for. |
Ah OK, I wasn't sure because it seemed like it required using both that parameter and the commandline flag when using mbsync. But it seems like it works now, I might have done something wrong when I tried it before. |
I think I missed something. If this has been/will be merged into the base branch, what config options do I need to enable to try it out? |
@bearcatsandor Yes, you need to enable the mbsync plugin and in the mbsync plusing you need to enable the fetch_performers option
There is a command-line option that should override this option, but it doesn't work, I will probably remove it and performer fetching will be only possible by enabling the option in the config, unless you believe there could be a need/demand for it (something like |
So, unless I'm being a doofus, I've placed that mbsync option into my config (the plugin was already enabled), and it doesn't appear to do anything. Looking at this page, I'm not sure how to tell if it's been merged into beet:master. |
Hey @bearcatsandor—no, I think you're understanding correctly! This PR has not been merged: you can tell because the top of the page still says "open" in green. #3995 is an example of a merged (purple!) PR, meaning the changes are now part of the branch they were proposed for. To try out these changes, you'll need to check out @dosoe's branch. |
Thanks for clarifying, @dosoe! This does help clarify things a bit for me. Nonetheless, it does solidify my position that this probably should not be part of mbsync. The original intention behind the mbsync plugin was to provide simple, fast alternative to re-importing your music—to just refresh exactly the same metadata that the original import process also provides. Like the documentation says:
That's the use case it's aiming for: when you know something has changed on MB (perhaps because you edited MB yourself!) and you'd like for your database to reflect that. Notably, it doesn't fetch any more metadata than the original import process does—it just fetches the same stuff only "fresher." From that perspective, it seems like fetching performer information would, in an ideal world, want to obey the same rules. It could get fetched on initial import and refreshed on So can I make the recommendation that this be put into a separate, special-purpose plugin, perhaps called |
It does make sense. However, to be honest, I'm not sure how to get the performer info without getting all the other MusicBrainz tags as well, as they get fetched during the call of If you create a new flexible tag, let's call it |
Yes, very clear; thanks for the explanation!! What makes this effort unique relative to other "apply some extra fields" efforts is the need to create a data-driven set of fields, rather than a fixed list, which implies the need to delete as well as add them. What do you think about adding a new event just for doing this? We could emit the event in the (If that does work, it would be good to do one thorough check to see if some other, existing event is close enough to the right "time" that it world already service this purpose...) |
One other possibility that I can think of, although I don't know how complicated it would be, would be to have some official way to associate specific tags with specific plugins. This might help resolve any potential conflicts between plugins and also allow for beets to automatically delete the old versions of tags. |
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
If I can help keep this alive, let me know. I've been eager for this for years. |
Hi! Yes, that's greatly appreciated. I just can't find the time to do it, sorry. |
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
An attempt to solve #1547 by fetching all artists involved in a recording. The artists have tag of the form
mb type - role (credit)
. For example, on this recording https://musicbrainz.org/recording/38fce51c-b8c9-4369-92d3-c354a8e09fd4 , tags would look like:mb vocals - bass vocals (Filippo)
andmb vocals sort - bass vocals (Filippo)
for the sort name, ormb vocals - choir vocals
If several artists have the same type, role and credit, then the tag will contain a list of artists separated by
;
. To avoid cluttering over time, I also change thembsync
plugin to remove all tags that start withmb
(with a space) that are not recovered when fetching the data again. This fetches all performers, engineers, arrangers (replacing thearranger
tag). Some type names (likeorchestra
) have been modified, just for the convenience of havingorchestra
instead ofperforming orchestra
orrecording engineer
instead ofrecording
.Finding all tags that start with
mb
is easy on singletons, but for albums I don't know how to do it in the way it is implemented inmbsync
. @sampsyo could you help me for that please? @bearcatsandor does this correspond to your idea of fetching all metadata? There is still more data, like recording place and date, but that's a start, and once this works, it should be easy to adapt it for more tags.