Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

Python+Mutagenで、複数の楽曲から情報(楽曲の長さなど)を高速に抽出

Python複数の楽曲データの長さを調べる時、真面目に楽曲ファイルを読み込んでNumpy配列のshapeを調べて…とすると、かなり時間がかかってしまいます数百曲以上になると、それだけで時間の無駄です

そこで、Mutagenを利用して、メタタグ情報から長さを得るPythonスクリプトを作りました。

mutagenの仕様上、今回はmp3, m4a (aac), flacファイルに限定します。

実行結果

flacとmp3とm4aの3つのファイルが入っているディレクトリパスをコマンドライン引数で与えました。

f:id:Kurene:20191116075330p:plain

速度比較(Mutagen v.s. librosa.load)

librosa.loadFLACファイル52曲の波形を読み込んで長さを算出した場合と比べました*1

  • Mutagen: 0.027 sec
  • librosa.load: 28.764 sec

実装

import os, sys
from pathlib import Path
from itertools import chain

from mutagen.mp4 import MP4
from mutagen.flac import FLAC 
from mutagen.mp3 import MP3


exts = ["flac", "mp3", "m4a", "aac"]

dirpath = sys.argv[1]
p = Path(dirpath)
filepaths = list(chain.from_iterable([list(p.glob(f"*.{ext}")) for ext in exts]))

print("Sampling Rate\tCh.\tLength\tExt.\tFilename")
for filepath in filepaths:
    filename = os.path.split(filepath)[1]
    filename, ext = os.path.splitext(filename)
    ext = ext.lower()
    if ext == ".mp3":
        audio_info = MP3(filepath).info
    elif ext in ["aac", ".m4a"]:
        audio_info = MP4(filepath).info
    elif ext == ".flac":
        audio_info = FLAC (filepath).info
    length = audio_info.length
    channels = audio_info.channels
    sample_rate = audio_info.sample_rate
    print(f"{sample_rate}\t\t{channels}\t{length:0.1f}\t{ext}\t{filename}")

補足

Mutagenを使えば、長さ以外の情報を抽出することができます。

以下の記事をご参照ください。

www.wizard-notes.com

www.wizard-notes.com

*1:リサンプリングをしないように、sr=Noneに設定