PLUGIN_NAME = 'MusicBee Compatibility' PLUGIN_AUTHOR = 'Volker Zell (and Sophist)' PLUGIN_DESCRIPTION = ''' Provide MusicBee compatible tags.

Note 1: The tags used by this plugin are only populated when you have checked Options / Metadata / Use track relationships.
Note 2: You may wish to use this with the Copy to Comment plugin, to which previous comment tag functionality has been moved.
Note 3: Info copied includes ALL Performers, as well as the Composer, Producer, Mixer etc.
MusicBee:               MusicBrainz tag:    MusicBrainz source:
Display Artist          DISPLAY ARTIST      artist
Artists:Artist          artist              artists (or split of artist if not existing)
Artists:Guest           GUEST ARTIST        taken from artist or title tags after feat./featuring/(feat./(featuring
Artists:Performer       PERFORMER           performer:*
Musician Credits List   TMCL                performer:*
Involved People List    IPLS                'Arranger', 'Engineer', 'Producer', 'Mixer', 'DJMixer', 'Remixer', 'Conductor'
Comment                 comment:            All the above
Misc                    MISC                'CatalogNumber', 'Barcode', 'ASIN', 'ReleaseType', 'ReleaseStatus', 'ReleaseCountry'
Note 4: I use the following additional entry in CustomTagConfig.xml for MusicBee
  ‹Tag id="Misc" id3v23="TXXX/MISC" id3v24="TXXX/MISC" wma="Misc" vorbisComments="Misc" mpeg="Misc" ape2="Misc" /›
and a couple of Virtual Columns with the following structure (because I ran out of the 16 custom columns) to access the MISC entries:
  Catalognumber = $Replace($First($Split(‹Misc›,Catalognumber:,2)),",",;)
''' PLUGIN_VERSION = "0.7" PLUGIN_API_VERSIONS = ["0.15.0", "0.15.1", "0.16.0", "1.0.0", "1.1.0", "1.2.0", "1.3.0"] import re from picard import log from picard.metadata import register_track_metadata_processor class MusicBeeCompatibility: re_artist_split = re.compile(r",\s*|\s+&\s+|\s+and\s+|\s+feat[.:]\s+|\s+featuring\s+").split re_featured_split = re.compile(r"\s+\(?feat[.:]\s+|\s+featuring\s+").split def musicbee_compatibility(self, album, metadata, *args): self.re_artist_split = MusicBeeCompatibility.re_artist_split self.re_featured_split = MusicBeeCompatibility.re_featured_split self.populate_performers(metadata) self.populate_artist(metadata) self.populate_tipl(metadata) self.populate_misc(metadata) def populate_performers(self, metadata): performers = [] for name in [name for name in metadata if name.startswith('performer:')]: self.txxx_add(metadata, 'TMCL', name[10:].title(), name, '; ') performers += dict.get(metadata, name) metadata["PERFORMER"] = " \x00".join(set(performers)) def populate_artist(self, metadata): if 'artists' in metadata: artists = dict.get(metadata, "artists") elif 'artist' in metadata: artists = self.re_artist_split(metadata['artist']) else: return guests = [] if 'artist' in metadata: guest = self.re_featured_split(metadata['artist'], 1)[1:] if guest: guests += self.re_artist_split(guest[0].rstrip(')')) if 'title' in metadata: guest = self.re_featured_split(metadata['title'], 1)[1:] if guest: guests += self.re_artist_split(guest[0].rstrip(')')) artists = [x for x in artists if x not in guests] metadata["DISPLAY ARTIST"] = metadata["artist"] metadata["artist"] = " \x00".join(artists) metadata["GUEST ARTIST"] = " \x00".join(guests) def populate_tipl(self, metadata): for name in ['Arranger', 'Engineer', 'Producer', 'Mixer', 'DJMixer']: if name.lower() in metadata: metadata[name] = " \x00".join(dict.get(metadata, name.lower())) for name in ['Arranger', 'Engineer', 'Producer', 'Mixer', 'DJMixer', 'Remixer', 'Conductor']: self.txxx_add(metadata, 'IPLS', name, name, '; ') def populate_misc(self, metadata): for name in ['CatalogNumber', 'Barcode', 'ASIN', 'ReleaseType', 'ReleaseStatus', 'ReleaseCountry']: self.txxx_add(metadata, 'MISC', name, name, '; ') def txxx_add(self, metadata, tagname, label, name, joiner): name = name.lower() if not name in metadata: return tag = dict.get(metadata, name) value = ', '.join(tag) if label: label += ': ' if tagname in metadata: metadata[tagname] += joiner + label + value else: metadata[tagname] = label + value try: from picard.plugin import PluginPriority register_track_metadata_processor( MusicBeeCompatibility().musicbee_compatibility, priority=PluginPriority.LOW ) except ImportError: log.warning( "Running %r plugin on this Picard version may not work as you expect. " "This plugin should be run after other plugins and if it runs before " "some changes to metadata may be incorrect.", PLUGIN_NAME ) register_track_metadata_processor(MusicBeeCompatibility().musicbee_compatibility)