def download_songs(mm, songs, template=None): if not songs: logger.log('NORMAL', "No songs to download") else: logger.log('NORMAL', "Downloading songs from Google Music") if not template: template = Path.cwd() songnum = 0 total = len(songs) pad = len(str(total)) for song in songs: songnum += 1 try: audio, _ = mm.download(song) except Exception as e: # TODO: More specific exception. logger.log('ACTION_FAILURE', "({:>{}}/{}) Failed -- {} | {}", songnum, pad, total, song, e) else: tags = audio_metadata.loads(audio).tags filepath = gm_utils.template_to_filepath( template, tags).with_suffix('.mp3') if filepath.is_file(): filepath.unlink() filepath.parent.mkdir(parents=True, exist_ok=True) filepath.touch() filepath.write_bytes(audio) logger.log('ACTION_SUCCESS', "({:>{}}/{}) Downloaded -- {} ({song['id']})", songnum, pad, total, filepath, song['id'])
def download_songs(mm, songs, template=None): logger.success(f"Downloading {len(songs)} songs from Google Music") if not template: template = Path.cwd() songnum = 0 total = len(songs) pad = len(str(total)) for song in songs: songnum += 1 try: audio, _ = mm.download(song) except Exception as e: # TODO: More specific exception. logger.log( 'FAILURE', f"({songnum:>{pad}}/{total}) Failed -- {song} | {e}" ) else: tags = audio_metadata.loads(audio).tags filepath = gm_utils.template_to_filepath(template, tags).with_suffix('.mp3') if filepath.is_file(): filepath.unlink() filepath.parent.mkdir(parents=True, exist_ok=True) filepath.touch() filepath.write_bytes(audio) logger.success( f"({songnum:>{pad}}/{total}) Downloaded -- {filepath} ({song['id']})" )
def get_audio_metadata(data): md = audio_metadata.loads(data) si = md["streaminfo"] tags = md["tags"] return { "tags": { "album": tags.get("album", None), "artist": tags.get("artist", None), "title": tags.get("title", None) }, "streaminfo": { "bitrate": si.bitrate, "duration": si.duration, "sample_rate": si.sample_rate } }
def test_loads_memoryview(): for fp in test_filepaths: audio_metadata.loads(memoryview(fp.read_bytes()))
def test_loads_bytearray(): for fp in test_filepaths: audio_metadata.loads(bytearray(fp.read_bytes()))
def test_loads_non_bytes_like(): with pytest.raises(ValueError): audio_metadata.loads(__file__)
def test_loads_non_audio(): with pytest.raises(UnsupportedFormat): with open(__file__, 'rb') as f: audio_metadata.loads(f.read())
def get_audio_cover(data): md = audio_metadata.loads(data) if len(md["pictures"]) == 0: return None else: return md["pictures"][0]