Extend whipper's tagging ability

Add PERFORMER & COMPOSER metadata tags to audio tracks (if available).
Composer(s) and performer(s) will be extracted from MusicBrainz
recording metadata by new _getComposers and _getPerformers
functions then there will be new properties added to each track
metadata. If those data are present it will be tagged as new tags
PERFORMER and COMPOSER.

Signed-off-by: ABCbum <kimlong221002@gmail.com>
Co-authored-by: JoeLametta <JoeLametta@users.noreply.github.com>
Signed-off-by: JoeLametta <JoeLametta@users.noreply.github.com>
This commit is contained in:
ABCbum
2020-01-15 13:13:53 +07:00
parent 150f0d5e91
commit 5cd96da6cb
2 changed files with 67 additions and 8 deletions

View File

@@ -153,18 +153,65 @@ class _Credit(list):
def _getWorks(recording):
"""Get "performance of" works out of a recording."""
"""
Get 'performance of' works out of a recording.
:param recording: recording entity in MusicBrainz
:type recording: dict
:returns: list of works being a performance of a recording
:rtype: list
"""
works = []
valid_work_rel_types = [
'a3005666-a872-32c3-ad06-98af558e99b0', # "Performance"
]
valid_type_id = 'a3005666-a872-32c3-ad06-98af558e99b0' # "Performance"
if 'work-relation-list' in recording:
for work in recording['work-relation-list']:
if work['type-id'] in valid_work_rel_types:
works.append(work['work']['id'])
if work['type-id'] == valid_type_id:
works.append(work['work'])
return works
def _getComposers(works):
"""
Get composer(s) from works' artist-relation-list.
:param works: list of works being a performance of a recording
:type works: list
:returns: sorted list of composers (without duplicates)
:rtype: list
"""
composers = set()
valid_type_id = 'd59d99ea-23d4-4a80-b066-edca32ee158f' # "Composer"
for work in works:
if 'artist-relation-list' in work:
for artist_relation in work['artist-relation-list']:
if artist_relation['type-id'] == valid_type_id:
composerName = artist_relation['artist']['name']
composers.add(composerName)
return sorted(composers) # convert to list: mutagen doesn't support set
def _getPerformers(recording):
"""
Get performer(s) from recordings' artist-relation-list.
:param recording: recording entity in MusicBrainz
:type recording: dict
:returns: sorted list of performers' names (without duplicates)
:rtype: list
"""
performers = set()
valid_type_id = {
'59054b12-01ac-43ee-a618-285fd397e461', # "Instruments"
'0fdbe3c6-7700-4a31-ae54-b53f06ae1cfa', # "Vocals"
'628a9658-f54c-4142-b0c0-95f031b544da' # "Performers"
}
if 'artist-relation-list' in recording:
for artist_relation in recording['artist-relation-list']:
if artist_relation['type-id'] in valid_type_id:
performers.add(artist_relation['artist']['name'])
return sorted(performers) # convert to list: mutagen doesn't support set
def _getMetadata(release, discid=None, country=None):
"""
:type release: dict
@@ -241,6 +288,8 @@ def _getMetadata(release, discid=None, country=None):
trackCredit = _Credit(
t.get('artist-credit', t['recording']['artist-credit']
))
recordingCredit = _Credit(t['recording']['artist-credit'])
works = _getWorks(t['recording'])
if len(trackCredit) > 1:
logger.debug('artist-credit more than 1: %r',
trackCredit)
@@ -250,11 +299,14 @@ def _getMetadata(release, discid=None, country=None):
track.artist = trackCredit.getName()
track.sortName = trackCredit.getSortName()
track.mbidArtist = trackCredit.getIds()
track.recordingArtist = recordingCredit.getName()
track.title = t.get('title', t['recording']['title'])
track.mbid = t['id']
track.mbidRecording = t['recording']['id']
track.mbidWorks = _getWorks(t['recording'])
track.mbidWorks = sorted({work['id'] for work in works})
track.composers = _getComposers(works)
track.performers = _getPerformers(t['recording'])
# FIXME: unit of duration ?
track.duration = int(t['recording'].get('length', 0))
@@ -301,7 +353,8 @@ def getReleaseMetadata(release_id, discid=None, country=None, record=False):
release_id, includes=["artists", "artist-credits",
"recordings", "discids",
"labels", "recording-level-rels",
"work-rels", "release-groups"])
"work-rels", "release-groups",
"work-level-rels", "artist-rels"])
_record(record, 'release', release_id, res)
releaseDetail = res['release']
formatted = json.dumps(releaseDetail, sort_keys=False, indent=4)

View File

@@ -416,6 +416,8 @@ class Program:
mbidTrack = track.mbid
mbidTrackArtist = track.mbidArtist
mbidWorks = track.mbidWorks
composers = track.composers
performers = track.performers
except IndexError as e:
logger.error('no track %d found, %r', number, e)
raise
@@ -449,6 +451,10 @@ class Program:
tags['MUSICBRAINZ_ALBUMARTISTID'] = mbidReleaseArtist
if len(mbidWorks) > 0:
tags['MUSICBRAINZ_WORKID'] = mbidWorks
if len(composers) > 0:
tags['COMPOSER'] = composers
if len(performers) > 0:
tags['PERFORMER'] = performers
# TODO/FIXME: ISRC tag