beets
beets copied to clipboard
acousticbrainz: Add tag mappings for AcousticBrainz values
Problem
The acousticbrainz tag don't seem to be writed, but a search on theses tags in beet work well.
$ beet -vv write "Electric Soul"
user configuration: /home/wargreen/.config/beets/config.yaml
data directory: /home/wargreen/.config/beets
plugin paths:
Sending event: pluginload
inline: adding item field multidisc
library database: /home/wargreen/.config/beets/library.db
library directory: /media/wargreen/ebf12476-be6c-4f3f-94e3-0d93b255464f/Stock/MuZiKs/FlacLib
Sending event: library_opened
Zenzile - Electric Soul - Scars
bpm: 110 -> 109.997833252
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - No Idol
bpm: 152 -> 152.094009399
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - Mind Control
bpm: 155 -> 155.072387695
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - Stay
bpm: 126 -> 126.000022888
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - Yuri's Porthole
bpm: 109 -> 109.920982361
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - Chewin' Mi Mic
bpm: 139 -> 139.937774658
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - Over/Time
bpm: 100 -> 100.005722046
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile - Electric Soul - Man Made Machine
bpm: 151 -> 151.209442139
Sending event: write
Sending event: after_write
Sending event: database_change
Zenzile feat. Winston McAnuff - Electric Soul - Magic Number
bpm: 125 -> 125.937271118
Sending event: write
Sending event: after_write
Sending event: database_change
Sending event: cli_exit
beet list danceable:0.8..1 "Electric Soul"
Zenzile - Electric Soul - Mind Control
Zenzile - Electric Soul - Yuri's Porthole
Zenzile - Electric Soul - Chewin' Mi Mic
Zenzile - Electric Soul - Over/Time
For exemple on one of theses files :
mediainfo 03\ Mind\ Control.flac
General
Complete name : 03 Mind Control.flac
Format : FLAC
Format/Info : Free Lossless Audio Codec
File size : 30.3 MiB
Duration : 4 min 55 s
Overall bit rate mode : Variable
Overall bit rate : 858 kb/s
Album replay gain : -7.95 dB
Album replay gain peak : 1.000000
Album : Electric Soul
Album/Performer : Zenzile / Zenzile
Part : 1
Part/Total : 1
Track name : Mind Control
Track name/Position : 3
Track name/Total : 9
Performer : Zenzile
Label : Yotanka Productions
Genre : Chillout
Recorded date : 2012-09-24 / 2012
BPM : 155.07
Cover : Yes
Cover type : Cover (front)
Cover MIME : image/jpg
FMPS_PLAYCOUNT : 0
FMPS_RATING_AMAROK_SCORE : 0.09
ACOUSTID_FINGERPRINT : AQADtNqiZFmWJDjckfjxA0d-1MczqOjz4-Nx4DoO_cNxRKKF4wd_oS_SEy90HD5xnDh4_JCNv_hx6MeP57hR6cOVQedxNUF-FU10Eu2S4z3y5Rk0J8vRXMrx43mgKTmaMDouakT0HNMpND-eKD9-ePIznDnx4zu4xkXzaKgyqdiXEsePftCX5Sjl42ma4cd5lEq0H5PG4sdjBcyNa8H1486GZiTyF6cdPCfuwsdlTIfmiQ0e6vjn4MwF8w_yHU-PpxT8YVSFK6CPydFwvEcOo5JTPJMe6Mk1RPjhU0HW41SGJ4e-rIivNPhVwu_xHc_046XgC3-GrD9-TKEeuD7xetAD70c9EmciEXF-_NhFNE_BHE965Dv0H_GP-4HjG8-Dm8LhOMi74wn-CNVZhE-PBz8qchWoRFtRb8ijG7qOPMLZ4Gg6lMqPI1-iCloShCRZ4YpmfFEafEjjJXhwZsdztHHG4FTxzHh2ONTRSvgEPeB-IheaM83w4zHS_kiUfPiFJzD5KMF15XiaoD-aaxGeRsJ-_PhxFfnRj4Ky60JVTkSuKOtx453wp0Fz4StKBUc-kYHeFGl2PMmNrNpivHBE7TgT4iT4t3jCFSEvvAR9-EXF7ciXnPhzHPoT4ilxZscDLfWhfcGDO0PzQ2v04al45HAuvFFyfJPA50V__BaOu8gHMWsR7jgTHg9_PMHZgjkPN0Ep4cgnHVryoSsf5NIc4kuIkhLRRFyCPAroG08faKl6eGxKfMYP8T1KKTvO5ODyQO9xKjiOOoHYDeGz4_gDx2fw40saJjg8argYCXkFHiGXS8fxovw0VE4SHk4UIzQHXRMyB3_Qh_AT1ElwHZ-R69ASHeFCksGjE-ca9BmabNPxKMiP5wyaPzh8Cs_Iw9ZRyhnu43mGQ1ae4lOG60ONVyyqB_J6xMd12J7wtLiQUj705ch1VPQqpEk7KWj5QDtcIdeKi0TDnrhbIXeTBGrhOkeO57iOPCvxHJoerWgeHnkSHkd9NFwy_HhTNIxz4U1-PNrx4kf4ZYF-_Mj94bwSPM1QyoX_gVd25AkLKRaDOPdxP2AZJYdrXEhvJGeMLyn4gVFYSikcMyN8PGqRP0iIZzraKTglPE9wNuh75AaTKsQ73DrivAjDykO9xcF1BH5wbSb-op8GMzrO7MeTFk9E4_fROTYCVcePfHhTopm-o1byBJdwMTsuPD0-HakzQQfszfiBUPs6OGGe4IetEo9aXD_8I3wO1SdyOwl-VHRK-EKdxPiF_BnUPEeY7JPQJw8uxvhR92ierPiOM2hCMU-ISwk8_jgVFj76skSeiNDxD88e5MqOx0NzB-Wb44lxmbiPJ4zxRUirEH-OEo0zHY-PFmIsPRFyU4UzabhwS8WL92jiicZFBvlj6DmcI-fx6PhexGLwXIMWfujp4JSRw9WOZ8X34BqaRHE4vMmH__Dqw8_RR8h3HHgSDfkngXfIgD_6R8KUnMeXILmyI7eM547xC08rPDsunDmm9CbCa0Oi6hPe4biFJnmCO2iWB-9D_OhzNA9xHz2s7CHx_khs7UgvPMTbFH7KB11RLepxBl-NG0emZwmSJ2hmDU8yPPiP5kMv4okenNnxo8cdHMmVI_DRxQ8uNFdQfccR5lmCZD2F88GP80N3HdwjlKRHPPSC_mh6PC2aUMd1C98j4cyDfEqI5IMrKfgNv41xH3eOz7gUqikoHEdyhCGuBVfwHc2PPgz-EM-PUoeP45-OTEdSojqeG30ZkDluBhuX7ehzXHh6fBbODL2QLBqVB3mS44HHmMaN48e2Ncd3kFmj6DiReDJyJkEt6TgbwXqPO8d5_MfnGj94pEdyHs3S48nwHCd8fCH2B-dQqz3u48c-aDJ-HBOjiE3QqMHPYuex62huJKuaIsdz1GLSoEmOJp8y9FLwhht-1EfjMHiGccdR9dFRSNGTwaqEm4fftPj34j54_PLwIyeFKzOEPEdJEVfw4Gfh8sRznLLxTDL6HA5bnBqoS3iOMD106djdxMg_olEZVONO7KdwPR1OJcZuND0mUgqSlUeYJI0ZnD-O5mRQLg-FH-2PnwhP6FMa9IlznC-0tdCPH3wSpPqwfzh29ElA_XhyTNGUZXiRB8lzPBd86vgrXElpXFeBPkf_FI_i4z2OI-dx54RYFfmS4zn-o3kSo_lw4zdOHuq4DI0uVFp7nDnuFH9K4UpwHpEeHn4-7EeYrcedBd8V5MyhxWGOSBYPPscPZpoUR4V_YTw8JQtb9BmuE7_w6fhhn8QV6zgP1DryZEUp54O6C3ueIK0ePHlAk0XPo3ky5F2CTwf3Q7NhPIePHz-sqEfFaLlxQ3qIGyWDxilO4ctRPXLQnHnwIVed4aGUwid-HacEXh_CJloueIdvfOJBeA80MccVKcV__Ap-HLUCN-gDvXiO51LgD6-W4I-G5szQR9A34dWxZ0f4Hl_x40dOuDx6KQyhS8b1HPmD62giSUOdHjueKGEQPkLzkLiOPFo2XEs0OGbwBGeOH3z0oHnE4FkJ8_A5o96w6zgl5GrwJ9Ae7LvwNDh89Av0HM0e1MkV_AXzEPFgMOaAAgIYxIgxgpXDjQLKCSGEsUhZKwBgwUIBpRICMAiEkIQY4YDhgjCHkFMUCEKEUoIRopAggDVFhIDIEYABIIoxYoBBjBBEkGMEAQCMEMA4BASBDBHjgRGCOCQQgkIIBgRiCAhiABAGKQaIVAYIA5GmChFDBTCACMIQQowYiJABgBmHEIDcQUAYIcg4BhBijBoimDAaOIgAEwaBgYRAEACgBLAIGoUIMMAASARBjECJgCCGAICgQ8gBAQSBwFGikCOUCiUQ4UIYQIgSCGhlBEAGGFAMcQRAQRwDSADHBCICCCAMBVUZIKRACqhAgAAUE2QIFIAY44BEBAnijEIEAdUMUQAK6ZZCAhjkEGGMCWMMIcoJYJhECCkFjACAANQY1AAYIQjjhjAFiDCGICCAQwABwAxCRiOjjAMUKSYYogAJoxAhyCoCBGKAEGykUcAAhRAAAEHuGECOGkaAIEYJowxCShEChDBIIQQM1EAgAaBQjkiijEGGAEMABoY4wBgAABFGADSMICQcQggAwghCyBlkgkGKAGeIUpAIAggSQChGoBAEUMUUIlIAQEEACBLjKCAAUCuMEIAwBgAilFEAIABSQEsUcVY5QAnExBGgFABEKQQQYIIIohUiygBhAHIECAqgIc4hyIQGBjJEgANUA4CAgIAIQBSjFBjCgCLEIicBcMIM4gwA1CFiAGIGKwCkBABQbpQRDAGAkAWAAKQIAw0QIwxDmikhBBACAEAQM0YQqZAwzjFDmCJEQAWY0YASRgghTBACEDCIDcOBAI4pQwAwiiIGDIKgG8WQMQpRShBAwiAlgDBMMECNQIAJZzBxhBCkECFYMEeJMAQqYgACDBghCCMEEgcMIsQBLgRAAAFiHDLIEIWMgAAYARyS1jAglGCYMkMAAKQIAAAiAAiknFBMAIGIowAsAAIDWAEDiBACIECQGIYxCogAQgIgEGAQIWiEY4YZgJBBigAAgFRAIIQIB5IgBQ
ACOUSTID_ID : 273b55f7-5af2-4690-b4cf-696309f0b11f
ALBUMARTIST_CREDIT : Zenzile
ALBUMARTISTSORT : Zenzile
MUSICBRAINZ_ALBUMSTATUS : Official
MUSICBRAINZ_ALBUMTYPE : album
ARTIST_CREDIT : Zenzile
ARTISTSORT : Zenzile
ASIN : B008KSFBI0
CATALOGNUMBER : YO26
COMPILATION : 0
RELEASECOUNTRY : FR
DISCC : 1
INITIALKEY : A
PUBLISHER : Yotanka Productions
MUSICBRAINZ_RELEASEGROUPID : a7cd9c9e-611a-4df1-b319-254f068eb328
MUSICBRAINZ_RELEASETRACKID : dad1b578-6639-30a7-90d3-196ff9514603
MEDIA : CD
ORIGINALDATE : 2012-09-24
SCRIPT : Latn
TRACK : 3
TRACKC : 9
Audio
Format : FLAC
Format/Info : Free Lossless Audio Codec
Duration : 4 min 55 s
Bit rate mode : Variable
Bit rate : 812 kb/s
Channel(s) : 2 channels
Channel layout : L R
Sampling rate : 44.1 kHz
Bit depth : 16 bits
Compression mode : Lossless
Replay gain : -6.11 dB
Replay gain peak : 1.000000
Stream size : 28.7 MiB (95%)
Writing library : libFLAC 1.2.1 (UTC 2007-09-17)
Language : English
Setup
- OS: Debian SID
- Python version: Python 2.7.18, Python 3.9.1+
- beets version: 1.4.9-7
My configuration (output of beet config
) is:
directory: /media/wargreen/ebf12476-be6c-4f3f-94e3-0d93b255464f/Stock/MuZiKs/FlacLib
ignore: .AppleDouble ._* *~ .DS_Store
threaded: yes
plugins: acousticbrainz fromfilename web inline replaygain discogs mbsubmit chroma
ui:
color: yes
paths:
default: $albumartist/$album/%if{$multidisc,CD $disc/}$track $title
per_disc_numbering: yes
item_fields:
multidisc: 1 if disctotal > 1 else 0
replaygain:
backend: gstreamer
overwrite: no
auto: yes
targetlevel: 89
r128: [Opus]
pathfields: {}
album_fields: {}
chroma:
auto: yes
web:
host: 127.0.0.1
port: 8337
cors: ''
cors_supports_credentials: no
reverse_proxy: no
include_paths: no
acousticbrainz:
auto: yes
force: no
tags: []
discogs:
apikey: REDACTED
apisecret: REDACTED
tokenfile: discogs_token.json
source_weight: 0.5
user_token: REDACTED
mbsubmit:
format: $track. $title - $artist ($length)
threshold: medium
Indeed! These are "flexible attributes" and do not have tag mappings in beets. We could imagine changing this, but we'd need somebody to come up with a proposal for exactly how to map these fields to various formats.
We have write a plugin for Picard, the pull request is here https://github.com/metabrainz/picard-plugins/pull/304 In this plugin i popose tags with the form : AB.[classifier].[feature]=[value] . So we get tags as :
AB.DANCEABILITY.DANCEABLE : 0.637822628021
AB.DANCEABILITY.NOT DANCEABLE : 0.362177342176
AB.GENDER.FEMALE : 0.719979047775
AB.GENDER.MALE : 0.280020922422
AB.GENRE_DORTMUND.ALTERNATIVE : 0.000291061704047
AB.GENRE_DORTMUND.BLUES : 8.67772268975e-06
AB.GENRE_DORTMUND.ELECTRONIC : 0.999585092068
I hope that it is a good way ! For now we tag only the features in the "all" key of the highlevel AB json, cause other can be determined from theses. It work well for Vorbis, id3 and m4a tags.
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue 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.
Yes, it's still relevent. The plugin in Picard (with full AB tags) is merged and a little bit refactored by the Metabrainz team (https://github.com/metabrainz/picard-plugins/pull/308). So we can now tag files with this format : High level information as
AB:HI:DANCEABILITY:DANCEABLE : 0.637822628021
AB:HI:DANCEABILITY:NOT DANCEABLE : 0.362177342176
AB:HI:GENDER:FEMALE : 0.719979047775
AB:HI:GENDER:MALE : 0.280020922422
and low level information as :
AB:LO:TONAL:CHORDS_CHANGES_RATE : 0.0735122486949
AB:LO:TONAL:CHORDS_KEY : E
AB:LO:TONAL:CHORDS_SCALE : minor
AB:LO:TONAL:KEY_KEY : A
AB:LO:TONAL:KEY_SCALE : minor
I don't think have the knowledges for write a plugin for beets. Is someone can / want write it ?
OK! I'm marking this as a feature request—the task, should anyone choose to pick it up, would be to mirror the tag mappings that the new Picard plugin is now using.
I'd like to implement this, but am poking around kind of blindly currently :-) I need some advice @sampsyo, not urgent at all just if you find the time and point me in some directions that would be very very helpful.
I am currently looking at the write functions of the UI and the acousticbrainz plugin:
https://github.com/beetbox/beets/blob/master/beets/ui/commands.py#L1634
https://github.com/beetbox/beets/blob/master/beetsplug/acousticbrainz.py#L231
https://github.com/beetbox/beets/blob/master/beetsplug/acousticbrainz.py#L218 https://github.com/beetbox/beets/blob/master/beetsplug/acousticbrainz.py#L235
Am I on track at all? Sorry probably the beets codebase is just a little over my head still...
The main thing that would need to be done is to extend MediaFile, which contains all the mappings to specific tag formats. See the long list of MediaField
declarations, starting here:
https://github.com/beetbox/mediafile/blob/badcd224e79f28574ae97d832456e28fb659e26a/mediafile.py#L1770-L1775
@sampsyo thanks, that was excatly the information I needed to get started.
@wargreen and @sampsyo It turns out adding simple mappings is not as straight forward as it seemed on first sight. I added a few entries as a first proposal in a draft PR, please have a look: https://github.com/beetbox/mediafile/pull/59/files#diff-ee64633bc4c7068afdf80ffb992636621620b40719b197d09d1de8c408063d3eR2146
I will try to map everything that is available in beets flexible fields already. I found a list of those fields here: https://github.com/beetbox/beets/blob/master/beetsplug/acousticbrainz.py#L27
Some questions to make sure I proceed in the right direction.
@wargreen I installed Picard 2.7.2 macOS and your acousticbrainz plugin and used it to tag a few files that had AcousticBrainz entries online already. I also installed mediainfo
to see what's really been tagged and also to have a complete list on all the tag names.
@wargreen and @sampsyo I understand that StorageStyle should match those values you defined and be used in every mediaformat equally. But what are the things like MP3DescStorageStyle and MP4StorageStyle and ASFStorageStyle? I guess special additional tags (or human readable "long" names of the tags??) available in only the formats the names imply. Should I put the whole rather long "path" in there as well or is it sufficient to shorten stuff like I did in this example (leaving out AB, HI and DANCEABILITY):
danceable = MediaField(
MP3DescStorageStyle(u'Acousticbrainz Danceable'),
MP4StorageStyle(
'----:com.apple.iTunes:Acousticbrainz Danceable'
),
StorageStyle('AB:HI:DANCEABILITY:DANCEABLE'),
ASFStorageStyle('Acousticbrainz/Danceable'),
)
Using the mediainfo
tool I can't seem to view such "long" tag names. --help seems exhaustive. If one of you knows the right option to make these fields viewable please tell me. It would help to find out if and how how Picard tagged those.
Also with the gender field I am not sure how to map. In Picard tagged files we have two fields with probability of male or female:
ab:hi:gender:male : 0.291780203581
ab:hi:gender:female : 0.708219766617
In beets we have a single field named gender that saves either "male" or "female":
'highlevel': {
...
...
},
'gender': {
'value': 'gender'
},
Hi @wargreen thanks so much for getting back to me. Appreciated. Could you please move your answer to the PR over here: https://github.com/beetbox/mediafile/pull/59 (and then delete it in this beets issue here)
Sorry for the inconvenience, I probably should have posted my questions right into the PR initially. That was my bad. Thanks!!!
@wargreen should we close this one? since ab being discontinued, I've closed my pr around this feature already...sorry to see ab go but it is what it is :-(
Hi @JOJ0 Sorry for my absence... I thought that better programmers than me take this issue into his hands ! And i had lot of work. About your last question... Sure it's sad. But i feel like (according to the forum posts) that a project with the same idea can appear. So yes, maybe that we can close this one for now and wait, see and hope for a new database.