Music2EmotionをWindowsで動かしつつyoutubeのURLを指定で動くようにしてみる

初めに

音楽の感情ラベルのライブラリおよびモデルが公開されたので触っていきます

github.com

公式からspaceは出ています

huggingface.co

デモ

以下のように youtubeのURLを指定して実行すると音声のダウンロード + 分析をやってくれるようにします。

python sample_youtube.py https://youtu.be/Ljr2wMSBHqU

結果

🎵 **Music Emotion Recognition Results [【Offical Music Video】みむかゥわナイストライ / Mimukauwa Nice Try]** 🎵
--------------------------------------------------
🎭 **Predicted Mood Tags:** christmas, energetic, fast, fun, funny, game, groovy, happy, holiday, party, positive, retro, sexy, sport, summer, upbeat
💖 **Valence:** 6.30 (Scale: 1-9)
⚡ **Arousal:** 7.49 (Scale: 1-9)
--------------------------------------------------

(みむかゥわナイストライ なのはちょうどハマっているからです)

開発環境

  • Windows11

環境構築

まずは環境を作ります。公式が Python3.10がいいと言っているので3.10で作っていきます。

uv venv -p 3.10
.venv\Scripts\activate 

次にライブラリを入れていきます。

uv pip install -r .\requirements.txt 

torchはcuda対応を入れます

uv pip install torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1 --index-url https://download.pytorch.org/whl/cu121 

ここでサンプルのコードは動くようになります。

次にyoutubeからダウンロードしてffmgpeでmp3に変換できるようにしていきます。

youtubeの動画ダウンロード用のライブラリを入れます

uv pip install yt-dlp

ffmpeg周りは以下からダウンロードしてパスを追加すれば動きます(長いので省略します)

ffmpeg.org

引数にURLを指定して実行する

サンプルコードを修正していきます。

import os
import sys
import yt_dlp
from music2emo import Music2emo

def download_audio_from_youtube(url, output_dir="inference/input"):
    # 出力ディレクトリがなければ作成
    os.makedirs(output_dir, exist_ok=True)
    
    # yt_dlpのオプション設定(出力ファイル名は固定: tmp.mp3)
    ydl_opts = {
        'format': 'bestaudio/best',
        'outtmpl': os.path.join(output_dir, 'tmp.%(ext)s'),
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
        'noplaylist': True,
        'quiet': True,
    }
    
    # yt_dlpで情報抽出とダウンロードを実施
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        title = info.get('title', 'Unknown Title')
    
    # 固定ファイル名tmp.mp3を指定
    output_file = os.path.join(output_dir, "tmp.mp3")
    return output_file, title

def main():
    # コマンドライン引数からURLを取得
    if len(sys.argv) < 2:
        print("使い方: python sample_youtube.py <YouTube URL>")
        sys.exit(1)
    
    input_audio = sys.argv[1]
    
    # URLの場合はダウンロードしてmp3に変換
    if input_audio.startswith("http"):
        input_audio, video_title = download_audio_from_youtube(input_audio)
    else:
        # URLでなければローカルファイルとみなす
        video_title = os.path.basename(input_audio)
    
    # Music2emoで音楽感情認識を実行
    music2emo = Music2emo()
    output_dic = music2emo.predict(input_audio)
    
    valence = output_dic["valence"]
    arousal = output_dic["arousal"]
    predicted_moods = output_dic["predicted_moods"]
    
    # 結果表示(動画タイトルを含む)
    print(f"\n🎵 **Music Emotion Recognition Results [{video_title}]** 🎵")
    print("-" * 50)
    print(f"🎭 **Predicted Mood Tags:** {', '.join(predicted_moods) if predicted_moods else 'None'}")
    print(f"💖 **Valence:** {valence:.2f} (Scale: 1-9)")
    print(f"⚡ **Arousal:** {arousal:.2f} (Scale: 1-9)")
    print("-" * 50)

if __name__ == "__main__":
    main()

上記を以下のコマンドで実行します

python sample_youtube.py url

以下が実行結果です

🎵 **Music Emotion Recognition Results** 🎵
--------------------------------------------------
🎭 **Predicted Mood Tags:** christmas, energetic, fast, fun, funny, game, groovy, happy, holiday, party, positive, retro, sexy, sport, summer, upbeat
💖 **Valence:** 6.30 (Scale: 1-9)
⚡ **Arousal:** 7.49 (Scale: 1-9)
--------------------------------------------------