def run(cls):
        data_folder = os.path.join('..', 'data')
        mp3_files = get_filenames_in_dir(data_folder, keyword='*.mp3')[0]
        audio_metadata = AudioMetadata(get_work_attributes=True,
                                       print_warnings=True)

        for ii, m in enumerate(mp3_files):
            save_file = os.path.splitext(m)[0] + '.json'
            if os.path.exists(save_file):
                temp_mbid = json.load(open(save_file))['mbid']
                if temp_mbid not in m:
                    print(m + ": does not match " + temp_mbid)
                continue

            print('{0:d}: {1:s}'.format(ii, m))
            # Get audio metadata
            audio_meta = audio_metadata.from_musicbrainz(m)

            vocal_instrument = []
            for a in audio_meta['artists']:
                choir_bool = a['type'] == 'vocal' and \
                             'attribute-list' in a.keys() and \
                             'choir_vocals' in a['attribute-list']
                if choir_bool:
                    vocal_instrument.append(a['attribute-list'])
                elif a['type'] in ['conductor']:
                    pass
                else:
                    vocal_instrument.append(a['type'])

            audio_meta['instrumentation_voicing'] = \
                cls.check_voice_instrumentation(vocal_instrument)

            json.dump(audio_meta, open(save_file, 'w'), indent=4)
def test_recording_mbid_metadata():
    # get the recording metadata
    audio_metadata = AudioMetadata(get_work_attributes=True,
                                   print_warnings=True)
    mbid = '5cbd1b2d-d1ef-4627-a4d4-135a95de2b69'

    mbid_meta = audio_metadata.from_musicbrainz(mbid)

    # load the metadata computed earlier
    saved_meta = _get_saved_meta(mbid + '.json')

    assert mbid_meta == saved_meta, 'test_recording_mbid_metadata failed'
def test_audio_metadata():
    # get the recording metadata
    audio_metadata = AudioMetadata(get_work_attributes=True,
                                   print_warnings=True)
    mp3file = os.path.join(_curr_folder, '..', '..', 'sampledata',
                           'huzzam_fasil.mp3')
    audio_meta = audio_metadata.from_musicbrainz(mp3file)

    # load the metadata computed earlier
    saved_meta = _get_saved_meta('audio_meta.json')

    # remove paths since they are both relative to something else
    audio_meta.pop("path", None)
    saved_meta.pop("path", None)

    assert audio_meta == saved_meta, 'test_audio_metadata failed'
Example #4
0
def get_meter_from_rec(recording_ID):
    '''
    automatically extract the meter from the metadata of the recording by ID (MusicBrainzID)
    '''

    # otherwise for makam
    from makammusicbrainz.audiometadata import AudioMetadata
    audioMetadata = AudioMetadata(get_work_attributes=True,
                                  print_warnings=True)

    audio_meta = audioMetadata.from_musicbrainz(recording_ID)
    try:
        usul_type = audio_meta['usul'][0]['attribute_key']

    except:
        if recording_ID == '7aec9833-6482-4917-87bd-e60c7c1dae3c':
            usul_type = 'kapali_curcuna'
        else:
            sys.exit('no usul type can be automatically fetched')

    return usul_type
 def __init__(self, get_recording_rels=False):
     self._audioMetadata = AudioMetadata(
         get_work_attributes=False, print_warnings=False)
     self._workMetadata = WorkMetadata(
         get_recording_rels=get_recording_rels, print_warnings=False)
class MusicBrainzMetadata(object):
    def __init__(self, get_recording_rels=False):
        self._audioMetadata = AudioMetadata(
            get_work_attributes=False, print_warnings=False)
        self._workMetadata = WorkMetadata(
            get_recording_rels=get_recording_rels, print_warnings=False)

    @property
    def get_recording_rels(self):
        return self._workMetadata.get_recording_rels

    @get_recording_rels.setter
    def get_recording_rels(self, value):
        self._workMetadata.get_recording_rels = value

    def crawl_musicbrainz(self, mbid):
        if mbid is None:  # empty mbid
            return {'makam': {}, 'form': {}, 'usul': {}, 'name': {},
                    'composer': {}, 'lyricist': {}}

        try:  # attempt crawling
            mbid = self._parse_mbid(mbid)
            try:  # assume mbid is a work
                data = self._workMetadata.from_musicbrainz(mbid)
                data['work'] = {'title': data.pop("title", None),
                                'mbid': data.pop('mbid', None)}
            except musicbrainzngs.ResponseError:  # assume mbid is a recording
                data = self._audioMetadata.from_musicbrainz(mbid)
                data['recording'] = {'title': data.pop("title", None),
                                     'mbid': data.pop('mbid', None)}
                if self.get_recording_rels:
                    warnings.warn(u"Recording mbid is given. Ignored "
                                  u"get_recording_rels boolean.", stacklevel=2)

            self._add_mb_attributes(data)
            return data
        except musicbrainzngs.NetworkError:
            warnings.warn("Musicbrainz is not available, skipping metadata "
                          "crawling...", stacklevel=2)
            return {'makam': {}, 'form': {}, 'usul': {}, 'name': {},
                    'composer': {}, 'lyricist': {}, 'url': ''}

    @staticmethod
    def _add_mb_attributes(data):
        # scores should have one attribute per type
        for attr in ['makam', 'form', 'usul']:
            try:
                data[attr] = data[attr][0]
            except (IndexError, KeyError):
                warnings.warn(
                    "Missing the {0:s} attribute in MusicBrainz".format(attr),
                    stacklevel=2)
                data.pop(attr, None)

    @staticmethod
    def _parse_mbid(mbid):
        o = urlparse(mbid)

        # if the url is given get the mbid, which is the last field
        o_splitted = o.path.split('/')
        mbid = o_splitted[-1]

        return mbid

    @staticmethod
    def validate_mb_attribute(attrib_dict, score_attrib, scorename):
        is_attribute_valid = True
        if 'mb_attribute' in score_attrib.keys():  # work
            skip_makam_slug = ['12212212', '22222221', '223', '232223', '262',
                               '3223323', '3334', '14_4']
            if score_attrib['symbtr_slug'] in skip_makam_slug:
                warnings.warn(u'{0:s}: The usul attribute is not stored in '
                              u'MusicBrainz.'.format(scorename), stacklevel=2)
            else:
                if not score_attrib['mb_attribute'] == \
                        attrib_dict['dunya_name']:
                    # dunya_names are (or should be) a superset of the
                    # musicbrainz attributes
                    is_attribute_valid = False
                    if score_attrib['mb_attribute']:
                        warn_str = u'{0:s}, {1:s}: The MusicBrainz ' \
                                   u'attribute does not match.' \
                                   u''.format(scorename,
                                              score_attrib['mb_attribute'])

                        warnings.warn(warn_str.encode('utf-8'), stacklevel=2)
                    else:
                        warnings.warn(u'{0:s}: The MusicBrainz attribute does'
                                      u' not exist.'.format(scorename),
                                      stacklevel=2)
        return is_attribute_valid

    @staticmethod
    def validate_mb_attribute_tag(attrib_dict, score_attrib, scorename):
        is_attribute_valid = True
        has_mb_tag = 'mb_tag' in score_attrib.keys()
        if has_mb_tag and score_attrib['mb_tag'] not in attrib_dict['mb_tag']:
            is_attribute_valid = False

            warn_str = u'{0!s}, {1!s}: The MusicBrainz tag does not match.'.\
                format(scorename, score_attrib['mb_tag'])

            warnings.warn(warn_str.encode('utf-8'), stacklevel=2)
        return is_attribute_valid