def scan_fast(path, _read_id3_hook=None): """Quickly produce an AudioFile object for the file at 'path'. This function avoids expensive calculations by assuming that the file is fully and correctly tagged. It never sets the 'payload' field. The 'duration_ms' field will be set based on the TLEN tag, if present. The 'frame_count' and 'frame_size' will be set based on the CHIRP-specific TXXX tags, if present. Args: path: The path to an MP3 file. _read_id3_hook: An optional callable that takes a path and returns mutagen ID3 data. Passing in None (the default) uses a default implementation. This argument should only be used for testing. Returns: An AudioFile object describing the file at 'path', or None if it does not appear to be a valid MPEG file. """ au_file = AudioFile() au_file.path = path au_file.mutagen_id3 = (_read_id3_hook or _get_mp3)(path) if au_file.mutagen_id3 is None: return None this_ufid = au_file.mutagen_id3.get(constants.MUTAGEN_UFID_KEY) if this_ufid: try: au_file.volume, au_file.import_timestamp, au_file.fingerprint = ( ufid.parse(this_ufid.data)) except ValueError: pass # Note we use the fact that mutagen_id3 is actually a mutagen.MP3 object. au_file.mp3_header = mp3_header.from_mutagen(au_file.mutagen_id3) # We assume that TLEN is accurate. Note that it would make sense to # use au_file.mutagen_id3.info.length for this, but mutagen's length # computation is not reliable. au_file.duration_ms = _tag_to_int(au_file, "TLEN") # Try to get the frame_size and frame_count from the tags. Again, # we assume these are accurate. au_file.frame_count = _tag_to_int(au_file, constants.TXXX_FRAME_COUNT_KEY) au_file.frame_size = _tag_to_int(au_file, constants.TXXX_FRAME_SIZE_KEY) # Try to pull the album ID out of a a tag. au_file.album_id = _tag_to_int(au_file, constants.TXXX_ALBUM_ID_KEY) return au_file
def test_from_mutagen(self): mp3 = mutagen.mp3.MP3() class MockInfo(mutagen.mp3.MPEGInfo): def __init__(self): pass mp3.info = MockInfo() mp3.info.sample_rate = 12345 mp3.info.bitrate = 123456 mp3.info.mode = mp3_header.STEREO hdr = mp3_header.from_mutagen(mp3) self.assertEqual(12345, hdr.sampling_rate_hz) self.assertEqual(123.456, hdr.bit_rate_kbps) self.assertEqual(mp3_header.STEREO, hdr.channels) self.assertEqual("stereo", hdr.channels_str) self.assertEqual(None, hdr.protected) self.assertEqual(None, hdr.padding)