Spotify APIでBPMが一定の曲プレイリストを作成する ~全ての音楽愛好家のためのSpotify API ep 4~

python
python

Spotify APIでプレイリストの操作ができるらしい。
BPM一定の楽曲プレイリストを作成してみよう。

記事①:PythonでSpotify APIを使ってみる ~全ての音楽愛好家のためのSpotify API ep 1~
記事②:曲のテンポ、コードを取得する ~全ての音楽愛好家のためのSpotify API ep 2~
記事③:Spotify APIで分析するコロナ禍が音楽に与えた影響 ~全ての音楽愛好家のためのSpotify API ep 3~

前回までは、楽曲分析にSpotify APIを使用してみました。
しかし、出来ることはこんなもんじゃないです。
今回は、自分のプレイリストを作成してみたいと思います。

ところで、皆さんはどんな時に音楽を聴いて言いますか?
自宅、車、散歩、ジョギング(もちろん、自転車はNGです)などいろいろなタイミングがあると思います。
私は歩きながら音楽を聴くことがありますが、たまに歩いている速度と音楽のテンポが同期して、非常に軽快に歩ける事があります。
歩調に近いBPMの曲を集めたプレイリストをつくれば、気持ちよく歩けそうですね
作ってみましょう!!

普通に好きな曲を集めてプレイリストを作るのだったら、APIを使う必要はないです。
しかし、特殊な条件のプレイリストを作るには、APIは もってこいです。
(2021年5月30日:学習開始100日目 PyQさんで勉強中!)←100日達成!!

オンラインPython学習サービス「PyQ™(パイキュー)」


音楽がパシっとはまって気持ち良いというと、「ベイビー・ドライバー」っていう映画を思い出します。
犯罪組織のドライバーをやっている主人公のストーリーですが、劇中のあらゆる音(自動車のエンジン、歩く靴音、銃撃音などなど)がBGMとシンクロします。
何言っているか分からないかもしれませんが、冒頭シーンを見てもらえば分かってもらえると思います。(公式YouTubeに飛びます。)
全編このスタイリッシュさが続く、とにかく見ていて気持ちいい映画です。
やっぱり音ハメは最高にクールです。


オシャレな曲で固められたサウンドトラックはこちらです。

という事で私も音ハメしていきましょう。

最終のプログラムはGitHubに置いておきます。

1.Spotify APIを使おう

Spotify APIはSpotifyの所有しているバックデータを取得したり、Spotifyを操作したりできるAPIです。公式のWeb API Tutorial

Spotify APIを使うには、Spotifyの登録が必要です。
また、spotipyというライブラリを使っていくので、このインストールも必要です。
そのあたりは、PythonでSpotify APIを使ってみる ~全ての音楽愛好家のためのSpotify API ep 1~に記載しているので、ご参照ください。

過去分は、ここで終了です。
しかし、プレイリスト操作にはもうひと手間必要です。

2.アクセス認証① ~ディベロッパーの編集~

ここが一番手間取りました。

Spotify APIのGitHubを参考に進めました。

まずは、SpotifyアプリのRedirect URIsを設定します。

まずSpotifyデベロッパーのダッシュボードページにアクセスし、ログインします。
デベロッパーの登録とアプリの作成はPythonでSpotify APIを使ってみる ~全ての音楽愛好家のためのSpotify API ep 1~を参考にしてください。
アプリの作成までは完了しているものとします。

作ったアプリをクリックします。

次に、「EDIT SETTING」をクリックします。

Redirect URIを設定します。
Spotify APIのGitHubにRedirect URIの例として「http://localhost:8888/callback」が登録されており、これを使ってみます。

Spotifyデベロッパー上での設定はこれで終了です。

3.アクセス認証② ~トークン認証~

ここも難しかったです。
Spotify Web APIで明るい楽曲のみのプレイリストを作成するを参考にさせていただきました。

APIからそれぞれ個別のアカウントにアクセスするため、アカウントのIDを知っておく必要があります。

SpotifyのHPにアクセスして、アカウント情報をクリックします。

ユーザー名にランダムな文字列があるので、コピペします(後で使います)。

では、プログラムを書いていきましょう。

「username」、「my_id」、「my_secret」、「redirect_uri」はそれぞれの値を入力します。

Scopeは、「どこまでアクセスする権限を付与するか?」という事のようです。
Using Scopesに詳細が書いてあります。
ここでは、いろいろな操作を出来るようにscopeはいろいろと設定しています。
以下のプログラムはこちらの
Spotify Web APIで明るい楽曲のみのプレイリストを作成する
をかなり引用させていただいております。

import spotipy
import spotipy.util as util

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)

一旦このプログラムを実行してみます。

うまく行くと、Spotifyのログイン画面が開きます。

ログインすると、以下の画面が開きます。

「同意する」をクリックすると認証完了です。
うまく行くとこんな画面が開きます

ここまで来れば、認証できてます。

4.プレイリストを作ってみよう①

では早速プレイリストを作ってみましょう。

import spotipy
import spotipy.util as util

#入力パート Input part
creat_playlist = 'test_list_XXX'

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)

spotify.user_playlist_create(user = username, name=creat_playlist)

これを実行してみると、Spotifyのアカウントに新たなプレイリストが作成されました。

では、次にできたプレイリストに曲を追加してみましょう。
映画「ベイビー・ドライバー」の冒頭曲、The Jon Spencer Blues Explosion の「Bellbottoms」を加えてみましょう。
「user_playlist_add_tracks」モジュールを使うとプレイリストに曲を追加できます。
作成したプレイリストのURLと追加したい曲のURLを設定しています。

import spotipy
import spotipy.util as util

#入力パート Input part
creat_playlist = 'test_list_XXX'

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)

play_list = 'https://open.spotify.com/playlist/XXXXXXXXXXXX'
track_URL = 'https://open.spotify.com/track/6NJQpFNkDCMaRBogIi9sOI'

spotify.user_playlist_add_tracks(username, play_list, track_URL)

これを実行するとエラーが出ます。
どうやらtrack_URLはリスト型で与える必要があるようです。

import spotipy
import spotipy.util as util

#入力パート Input part
creat_playlist = 'test_list_XXX'

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)

play_list = 'https://open.spotify.com/playlist/XXXXXXXXXXXX'
track_URL = 'https://open.spotify.com/track/6NJQpFNkDCMaRBogIi9sOI'

spotify.user_playlist_add_tracks(username, play_list, [track_URL])

これでプレイリストに曲が追加されました。

まずは、プレイリストの作成と曲の追加が出来るところまできました!

5.プレイリストを作ってみよう②

ここまで操作では、マニュアル操作が多かったですね。
もっと自動で動かせるようにしたいと思います。
やりたいのは、「プレイリスト作成」と「プレイリストURL取得」を同時にしたいです。

試行錯誤しましたが、ここでは結果のみ示します。
やっていることは
「プレイリスト作成」
→「ユーザーのプレイリスト検索」
→「作成したプレイリストと同じ名前のプレイリストのURLを返す」
という事です。

import spotipy
import spotipy.util as util

#入力パート Input part
creat_playlist = 'test_list_YYY'

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)

def creat_play_list(list_name):
    spotify.user_playlist_create(username, name = list_name)
    list_data = spotify.user_playlists(user = username)
    for i in range(list_data['total']):
        play_list_name = list_data['items'][i]['name']
        if play_list_name == list_name:
            url = list_data['items'][i]['external_urls']['spotify']
        else:
            pass
    return(url)

play_list = creat_play_list(creat_playlist)
print(play_list)

これを実行すると、「プレイリストが作成される」と同時に「プレイリストのURL」が返ってきます。

では、一旦ここから離れましょう。

6.プレイリストに追加する曲を探そう

次は、「一定のBPMを持つ曲」を探しましょう。
やり方としては、
「元となるプレイリストからトラック情報を取り出し」
→「トラック情報から、一定のBPMを持つ曲を抽出」
→「URLをリスト型で保存する」
という流れです。

前回の記事で作成したプログラムをもとに作成しました。
グローバルチャートのプレイリストから、テンポ115~125の曲を抽出してみました。
(ちなみ、自分の気持ちい良いBPMはメトロノームで探しましょう。Pythonで自分だけのメトロノームをつくろう
長くなるので、作成過程の詳細は略します。

import spotipy
import spotipy.util as util
import time

#入力パート Input part
original_play_list = 'https://open.spotify.com/playlist/37i9dQZEVXbMDoHDwVN2tF'
set_tempo = 120 #center tempo
set_tempo_range = 5 # +- tempo range

#認証パート Authentication part
~~~~~略~~~~~
spotify = spotipy.Spotify(auth = token)

def set_tempo_track(original_play_list, set_tempo, set_tempo_range):
    list_data = spotify.playlist_tracks(original_play_list)
    track_num = list_data['total']
    if track_num > 100:
        track_num =100
    urls_list =[]
    for i in range(track_num):
        track_url = list_data['items'][i]['track']['external_urls']['spotify']
        urls_list.append(track_url)
    time.sleep(1) #1sec stop
    tempo_urls_list =[]
    for i in range(len(urls_list)):
        track_url = urls_list[i]
        track_feature = spotify.audio_features(track_url)[0]
        time.sleep(1)
        tempo = track_feature['tempo']
        if (set_tempo-set_tempo_range) <= tempo <= (set_tempo + set_tempo_range):
            tempo_urls_list.append(track_url)
        else:
            pass
    return(tempo_urls_list)

tempo_urls_list = set_tempo_track(original_play_list, set_tempo, set_tempo_range)
print(tempo_urls_list)
print('finish')

結果は以下のようになりました。

['https://open.spotify.com/track/37BZB0z9T8Xu7U3e65qxFy', 'https://open.spotify.com/track/6SRsiMl7w1USE4mFqrOhHC', 'https://open.spotify.com/track/4cG7HUWYHBV6R6tHn1gxrl', 'https://open.spotify.com/track/6f3Slt0GbA2bPZlz0aIFXN', 'https://open.spotify.com/track/5QO79kh1waicV47BqGRL3g', 'https://open.spotify.com/track/5uEYRdEIh9Bo4fpjDd4Na9']
finish

6曲のURLが取得できました。うまく出来てそうです。

7.BPMが一定の曲プレイリストを作成しよう

ここまで作ってきたプログラムをくっ付けて、
BPMが一定の曲プレイリスト
を作成しましょう。

import spotipy
import spotipy.util as util
import time

#入力パート Input part
creat_playlist = 'test_list_tempo120'
original_play_list = 'https://open.spotify.com/playlist/37i9dQZEVXbMDoHDwVN2tF'
set_tempo = 120 #center tempo
set_tempo_range = 5 # +- tempo range

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)


def creat_play_list(list_name):
    spotify.user_playlist_create(username, name = list_name)
    list_data = spotify.user_playlists(user = username)
    for i in range(list_data['total']):
        play_list_name = list_data['items'][i]['name']
        if play_list_name == list_name:
            url = list_data['items'][i]['external_urls']['spotify']
        else:
            pass
    return(url)


def set_tempo_track(original_play_list, set_tempo, set_tempo_range):
    list_data = spotify.playlist_tracks(original_play_list)
    track_num = list_data['total']
    if track_num > 100:
        track_num =100
    urls_list =[]
    for i in range(track_num):
        track_url = list_data['items'][i]['track']['external_urls']['spotify']
        urls_list.append(track_url)
    time.sleep(1) #1sec stop
    tempo_urls_list =[]
    for i in range(len(urls_list)):
        track_url = urls_list[i]
        track_feature = spotify.audio_features(track_url)[0]
        time.sleep(1)
        tempo = track_feature['tempo']
        if (set_tempo-set_tempo_range) <= tempo <= (set_tempo + set_tempo_range):
            tempo_urls_list.append(track_url)
        else:
            pass
    return(tempo_urls_list)

play_list = creat_play_list(creat_playlist)
tempo_urls_list = set_tempo_track(original_play_list, set_tempo, set_tempo_range)
time.sleep(1)
spotify.user_playlist_add_tracks(username, play_list, tempo_urls_list)
print('finish')

ところどころ、time.sleepを挟んでいるので、結構時間がかかります。
けど、「プレイリストの作成」と「曲の追加」が同時に達成できました!

ただ50曲から抽出した割に6曲しか集まりませんでした。
BPM115~125の割合が1割程度という事なのでしょうね。

では、「すでに作ったプレイリストにBPM一定の曲を追加するプログラム」を作成してみましょう。
こんな感じです。次は日本のヒットチャートから抽出して、プレイリストに追加してみます。

import spotipy
import spotipy.util as util
import time

#入力パート Input part
addition_playlist = 'https://open.spotify.com/playlist/XXXXXXXXX' #track adding playlist
original_play_list = 'https://open.spotify.com/playlist/37i9dQZEVXbKqiTGXuCOsB' #search playlist
set_tempo = 120 #center tempo
set_tempo_range = 5 # +- tempo range

#認証パート Authentication part
username = 'YOUR USER NAME'
my_id ='0000000000000000000000' #client ID
my_secret = '0000000000000000000000' #client secret
redirect_uri = 'Redirect URI' 

#アプリの権限付与に使用する
scope = 'user-library-read user-read-playback-state playlist-read-private user-read-recently-played playlist-read-collaborative playlist-modify-public playlist-modify-private'

token = util.prompt_for_user_token(username, scope, my_id, my_secret, redirect_uri)
spotify = spotipy.Spotify(auth = token)


def set_tempo_track(original_play_list, set_tempo, set_tempo_range):
    list_data = spotify.playlist_tracks(original_play_list)
    track_num = list_data['total']
    if track_num > 100:
        track_num =100
    urls_list =[]
    for i in range(track_num):
        track_url = list_data['items'][i]['track']['external_urls']['spotify']
        urls_list.append(track_url)
    time.sleep(1) #1sec stop
    tempo_urls_list =[]
    for i in range(len(urls_list)):
        track_url = urls_list[i]
        track_feature = spotify.audio_features(track_url)[0]
        time.sleep(1)
        tempo = track_feature['tempo']
        if (set_tempo-set_tempo_range) <= tempo <= (set_tempo + set_tempo_range):
            tempo_urls_list.append(track_url)
        else:
            pass
    return(tempo_urls_list)

tempo_urls_list = set_tempo_track(original_play_list, set_tempo, set_tempo_range)
time.sleep(1)
spotify.user_playlist_add_tracks(username, addition_playlist, tempo_urls_list)
print('finish')

これも実際に動かしてみて、プレイリストが操作できました。
最後の2つのプログラムはGitHubに置いておきます。

快適な音楽ライフを!!!

FIN.

PyQさんで勉強中!


コメント

タイトルとURLをコピーしました