はじめに
音楽分析を行う時には、音響信号だけでなく、大量の音源からのメタデータの抽出・編集・読み込み・書き込みが必要となることがあります。
手動でメタデータを管理する場合、 Mp3tag
のようなソフトウェアを使うのが楽ですが、大量の音源のメタデータを処理しようとすると手動では管理しづらいです。
そこで、今回は Python の Mutagen を用いたメタデータの抽出方法を紹介します。
MP3 の抽出は Mutagen の Example にサンプルコードがあるため、この記事ではMutagen を使って AAC (.m4a) 音源からメタデータを抽出してみます。
1. あるディレクトリの楽曲を全て捜索する
dirpath
に音源が入ったディレクトリのパスを入れることで、そのディレクトリの中の全ての m4a 音源のパスを逐次的に読み込みます。
ext = "m4a" dirpath = "music_data" for filepath in glob.glob(f"{dirpath}/*.{ext}"): print(filepath)
2. Mutagen で楽曲のメタデータを抽出する
Mutagen
を使います。
今回は AAC (.m4a) のみを対象としているため、mutagen.mp4.MP4
クラスを使います。
mutagen.mp4.MP4.info
のフィールドには、ビットレートのようなコーデックに関する情報が含まれています。
mutagen.mp4.MP4.tags
にはアーティスト情報のようなメタデータが辞書型で入っています。
各メタデータを抽出するキーについては、Mutagen
のドキュメントを参考にしてください。今回は、よく使いそうなメタデータのみ利用しています。
import glob from mutagen.mp4 import MP4 dirpath = "music_data" ext = "m4a" for filepath in glob.glob(f"{dirpath}/*.{ext}"): # Extract meta data # Refer to https://buildmedia.readthedocs.org/media/pdf/mutagen/latest/mutagen.pdf mp4 = MP4(filepath) track_title = mp4.tags["\xa9nam"][0] album = mp4.tags["\xa9alb"][0] artist = mp4.tags["\xa9ART"][0] year = mp4.tags["\xa9day"][0] #composer = mp4.tags["\xa9wrt"][0] #grouping = mp4.tags["\xa9grp"][0] #genre = mp4.tags["\xa9gen"][0] bitrate = mp4.info.bitrate length = mp4.info.length channels = mp4.info.channels sample_rate = mp4.info.sample_rate bits_per_sample = mp4.info.bits_per_sample codec = mp4.info.codec
3. pandas で表の作成+CSVを書き出す
Python でデータの処理をしている人にはお馴染みの pandas
(Python Data Analysis Library) を使って、
メタデータを表にまとめ、CSVで書き出しています。
今回は、大量の楽曲を処理するときに列(メタデータ)ごとにデータを管理した方が嬉しいと考え、辞書型から dataframe を作っています。
import pandas as pd header = ["artist", "album", "year"] di = {header[0]: [11, 21], header[1]: [12, 22], header[2]: [13, 23]} df = pd.DataFrame.from_dict(di) df.to_csv("data.csv", header=header, index=False)
4. 1~3 をまとめる
# Preparation ext = "m4a" dirpath = "music_data" tags_table = {"track_title": "\xa9nam", "album": "\xa9alb", "artist":"\xa9ART", "year": "\xa9day" } tags_list = list(tags_table.keys() info_list = ["bitrate", "length", "channels", "sample_rate", "bits_per_sample", "codec"] meta_list = tags_list + info_list meta_di = {meta: [] for meta in meta_list} filepath_list = glob.glob(f"{dirpath}/*.{ext}") # Extract meta-tags for each audiofile for filepath in filepath_list: mp4 = MP4(filepath) mp4_info_di = jsons.dump(mp4.info) for meta in meta_list: if meta in tags_list: val = mp4.tags.get(tags_table[meta], "KeyError")[0] else: val = mp4_info_di[meta] meta_di[meta].append(val) # Make dataframe@pandas and write csv df = pd.DataFrame.from_dict(meta_di) df["filepath"] = filepath_list df.to_csv("data.csv", header=meta_list+["filepath"], index=False, encoding='utf_8_sig')
補足
mutagen.mp4.MP4.tags
は、音源によってはメタデータが存在せず KeyError
となることがあります。従って、例外処理を入れてください。(例:KeyError
の時はval ="<KeyError>"
とする)また、Value がリストのため複数の値が入っていることもあります。