はじめに
こちらの内容は、音楽データの分析および可視化に関するPythonコードを紹介する記事です。特に、バンド「ハヌマーン」の「アパルトの中の恋人達」の曲を例に、YouTubeから音声データをダウンロードし、音楽の特徴(テンポ、ピッチ、感情分析など)を抽出・解析する方法を実践します。
参考リンクまとめ
Pythonコード
# 完全統合版:YouTube → MP3 → 可視化 → テンポ解析 → 構造解析 → ピッチ/感情マッピング
# --- Step 1: ライブラリのインストール(Colab再起動後用) ---
!pip install yt-dlp pydub librosa scikit-learn --quiet
!apt install ffmpeg -y
# --- Step 2: YouTubeからMP3をダウンロード ---
import yt_dlp
import os
from pydub import AudioSegment
# ダウンロードするYouTube動画のURL
url = "https://www.youtube.com/watch?v=ahMb9c6jcRs" # 任意のYouTube動画URL
# 出力パス設定
output_path = "downloaded_audio.%(ext)s"
# yt-dlpの設定オプション
ydl_opts = {
'format': 'bestaudio/best', # 最も良い音質を選択
'outtmpl': output_path, # 出力ファイル名設定
'postprocessors': [{
'key': 'FFmpegExtractAudio', # MP3形式に変換
'preferredcodec': 'mp3', # MP3形式で保存
'preferredquality': '192', # 音質設定
}],
'quiet': True # 出力を抑制
}
# YouTubeから音声をダウンロードしてMP3に変換
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
# ダウンロードしたファイルの名前を変更
os.rename("downloaded_audio.mp3", "audio.mp3")
print("MP3変換完了") # 成功メッセージ
# --- Step 3: 音声読み込みと可視化 ---
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
# 音声ファイルを読み込み
y, sr = librosa.load('audio.mp3')
# 波形を表示
plt.figure(figsize=(10, 6))
librosa.display.waveshow(y, sr=sr)
plt.title("Waveform of the Audio")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.show()
# --- Step 4: テンポ解析 ---
# テンポの推定
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)
# テンポの表示
print(f"推定されたテンポ: {tempo} BPM")
# ビートの位置をプロット
plt.figure(figsize=(10, 6))
librosa.display.waveshow(y, sr=sr)
plt.vlines(librosa.frames_to_time(beat_frames), ymin=-1, ymax=1, color='r', alpha=0.7, label="Beats")
plt.title(f"Tempo Analysis: {tempo} BPM")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.legend()
plt.show()
# --- Step 5: ピッチ/感情マッピング ---
# ピッチを抽出
pitch, mag = librosa.core.piptrack(y=y, sr=sr)
# 最大ピッチを選択
index_max = mag[:, :].argmax(axis=0)
pitch_max = pitch[index_max, range(pitch.shape[1])]
# ピッチをプロット
plt.figure(figsize=(10, 6))
plt.plot(librosa.times_like(pitch_max), pitch_max, label='Pitch', color='g')
plt.title("Pitch Tracking")
plt.xlabel("Time (s)")
plt.ylabel("Frequency (Hz)")
plt.legend()
plt.show()
# 感情分析(仮にピッチとテンポに基づく簡単な感情マッピングを行う)
if tempo > 120 and np.mean(pitch_max) > 200:
emotion = "Energetic"
elif tempo < 80 and np.mean(pitch_max) < 150:
emotion = "Calm"
else:
emotion = "Neutral"
print(f"推定される感情: {emotion}")
# --- Step 6: スペクトログラム解析 ---
# スペクトログラムを計算
D = librosa.amplitude_to_db(librosa.stft(y), ref=np.max)
# スペクトログラムの表示
plt.figure(figsize=(10, 6))
librosa.display.specshow(D, sr=sr, x_axis='time', y_axis='log')
plt.colorbar(format='%+2.0f dB')
plt.title('Spectrogram')
plt.xlabel('Time (s)')
plt.ylabel('Frequency (Hz)')
plt.show()
# --- Step 7: コード認識 ---
# ピッチクラスを取得して、コードを認識する
chroma = librosa.feature.chroma_cens(y=y, sr=sr)
# コードをプロット
plt.figure(figsize=(10, 6))
librosa.display.specshow(chroma, x_axis='time', y_axis='chroma')
plt.colorbar(label='Chroma')
plt.title('Chroma Features (Chords)')
plt.xlabel('Time (s)')
plt.ylabel('Pitch Classes')
plt.show()
# --- Step 8: 和音と打楽器成分の分離 ---
# 音源分離(和音と打楽器)
harmonic, percussive = librosa.effects.hpss(y)
# 和音と打楽器の波形表示
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
librosa.display.waveshow(harmonic, sr=sr)
plt.title("Harmonic Component")
plt.subplot(2, 1, 2)
librosa.display.waveshow(percussive, sr=sr)
plt.title("Percussive Component")
plt.tight_layout()
plt.show()
# --- Step 9: リズムとテンポの詳細分析 ---
# 発音(オンセット)の検出
onset_frames = librosa.onset.onset_detect(y=y, sr=sr)
# オンセットの位置をプロット
plt.figure(figsize=(10, 6))
librosa.display.waveshow(y, sr=sr)
plt.vlines(librosa.frames_to_time(onset_frames), ymin=-1, ymax=1, color='r', alpha=0.7, label="Onsets")
plt.title("Rhythm and Onset Detection")
plt.xlabel("Time (s)")
plt.ylabel("Amplitude")
plt.legend()
plt.show()