PythonでSpotify API [audio_features編]

# 楽曲の解析情報
ぼくがSpotifyのAPIに手を出した大きな理由として、楽曲ごとの解析情報（それもかなりこまかい）が提供されているということがあります。

まぁ詳しく知っていたわけではないんですが、Spotifyを愛用していると、「こまかい情報あるよ」と言われるだけで、そうなんだろうなと思うわけです。
それくらいなんかオススメ楽曲とかの精度がよい。

で、頑張ってAPIのリファレンスとか読んでやってみているわけなんですが、リファレンスのリンクたどって英語読むのも飽きちゃうのでここにノートとしてまとめておきますね。

# どんな情報がとれる？
（ぼくが）楽曲の解析情報と呼んでいるものは、オブジェクト的には2つ。
`audio_features`と、`audio_analysis`です。

リファレンス読んでみたかんじ、ざっくりいうと
`audio_features`が**曲を全体的に見た**データで、`audio_analysis`が**曲を細かい単位に分割して分析した**ってかんじのデータ。

今回はaudio_featuresをまとめてみまーす

### audio_features

曲全体の印象を主に数値で表したオブジェクト。[情報の文字列検索](https://qiita.com/EkatoPgm/items/289b2efcdb5af49843c1)でも少し触れました。少しだけ。

表は[リファレンス](https://developer.spotify.com/documentation/web-api/reference-beta/#object-audiofeaturesobject)をふんわり訳したものです。
項目自体の意味もふんわりなので、詳しく知りたい人は英和辞書片手にリファレンスへ。

|キー|意味|
|:--|:--|
|acousticness|**その曲がどれくらいアコースティックなのか**を、0.0から1.0までの数字で表します。<br>どれくらいシンセとかエレキ楽器を使わずに演ってるかってこと。<br>多分だけど、「曲の中にアコースティックな部分（時間）がどれだけあるか」とニアイコール。|
|analysis_url|後述の`audio_analysis`へのURLを指します。|
|danceability|**その曲がどれだけ踊れるか楽曲なのか**を、0.0から1.0までの数字で表します。<br>要するにダンスミュージックっぽさ。テンポやリズムに基づいてるみたいだけどまぁ深く考えなくていいんじゃないかな。踊れば。|
|duration_ms|**楽曲の時間**をなんとミリ秒でお届け。|
|energy|**曲のエネルギー量**を0.0から1.0の以下略。<br>速くて騒々しい曲はエネルギーが高くなり、逆に静かでゆっくりな曲は低いようです。0.5はまさに冷静と情熱の間。ちがうか。|
|id|言わずもがな。|
|instrumentalness|**どれくらい歌(AhとかOhは歌に含まない)が無いか**を0.0から1.0で。<br>ラップのようなThe歌詞みたいな部分が多いほど、この値は低くなります。<br>公式によると、0.5を超えてればだいたいインストなんじゃねーかと。|
|key|**曲のキー**。<br>0 = C, 1 = C♯/D♭, 2 = D,...のように対応づけられた値が入ります。|
|liveness|**ライブっぽさ**。0.0から1.0。<br>基準は「観客がいるかどうか（歓声とかかな）」で、0.8を超えたらまぁライブ音源でしょと。2階席聞こえるー？|
|loudness|平たく言って**うるささ**。曲全体のデシベル値を平均したものです。|
|mode|**スケール**。音楽やらない人は興味ないかな。<br>メジャーが1でマイナーが0。|
|speechiness|**喋りっぽさ**(0.0〜1.0)。トークショーやドラマトラックだと高くて、音楽なら低い。<br>以下が目安らしい。<br>0.66以上：ほぼ喋り<br>0.33〜0.66：喋りっぽい部分を含む曲（ラップとか）<br>0.33以下：(ほぼ)喋りなし|
|tempo|**曲全体のBPMの平均**。|
|time_signature|**曲全体の拍子**。たぶん途中で拍子が変わる曲はダメ。|
|track_href|**トラックの詳細へのリンク**|
|type|オブジェクトの種類。確定で**文字列”audio_features”**|
|uri|**曲のURI**|
|valence|**曲のポジティブさ**(0.0〜1.0)。<br>これに関してはよくわからない。|

ちなみに表の中で範囲が0.0から1.0までとしているものは、小数点以下が細かく出ます。
ぽちぽち打ってみたところ、小数点第三位とか第四位は出てくる。


### とりあえずとってみる
ではとってみましょうか。
SpotifyAPIが初めてで、登録とかやってないしClientIDってなんやねん！！って方がいらっしゃったら[とにかく使ってみる編](https://qiita.com/EkatoPgm/items/15f1a61bc2fe01c8a0c9)とか読んでまずはAPI使ってみてくださいな。

以下のコードを書きます。

```python
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint

client_id = 'ClientIDの値'
client_secret = 'ClientSecretの値'
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)

sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

result = sp.audio_features('6KDmk0EF3Qk7zJfDDtRoF2')
pprint.pprint(result)
```

ちなみに`sp.audio_features()`の引数に指定しているIDはゴールデンボンバーさんの曲「令和」です。いい時代になるといいですね。

実行ドン

```
{'acousticness': 0.0939,
 'analysis_url': 'https://api.spotify.com/v1/audio-analysis/6KDmk0EF3Qk7zJfDDtRoF2',
 'danceability': 0.573,
 'duration_ms': 241680,
 'energy': 0.955,
 'id': '6KDmk0EF3Qk7zJfDDtRoF2',
 'instrumentalness': 0,
 'key': 7,
 'liveness': 0.336,
 'loudness': -3.352,
 'mode': 0,
 'speechiness': 0.135,
 'tempo': 142.021,
 'time_signature': 4,
 'track_href': 'https://api.spotify.com/v1/tracks/6KDmk0EF3Qk7zJfDDtRoF2',
 'type': 'audio_features',
 'uri': 'spotify:track:6KDmk0EF3Qk7zJfDDtRoF2',
 'valence': 0.619}
```

なるほどね？

「令和」が、なかなかエネルギッシュでそこそこポジティブな曲であることがわかりました（凡人の感想）
いろんな曲とって見てみたのですが、令和の`danceability`は、もうちょっと高くてもいいような気がしないでもない。


### 似たような曲を探してみる

ある特定の曲を気に入った時に、

**「あーこの曲と同じくらい盛り上がっていい雰囲気の曲ないかなー！？」**

ってことがひょっとしたらできるんじゃないかと思って、

殴り書きですが、こんなコードを組んでみました。

```python
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint

client_id = 'ClientIDの値'
client_secret = 'ClientSecretの値'
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)

sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

# 令和を取得
result = sp.audio_features('6KDmk0EF3Qk7zJfDDtRoF2') # 令和
reiwa = result[0]

# プレイリストを取得
result = sp.user_playlist('ユーザID','プレイリストID')

features = []
id_list = []
cnt = 0
for track in result['tracks']['items']:
  cnt += 1
  # プレイリスト内の曲のidを抜き出してリスト化
  id = track['track']['id']
  id_list.append(id)
	
  if cnt == 50:
    # audio_features()は50個が最大なので、一回取得する
    features.extend(sp.audio_features(id_list))
    cnt = 0
    id_list = [] 

cnt = 0
for feature in features:
  if (reiwa['tempo']-1) <= feature['tempo'] <= (reiwa['tempo']+1) and \
   (reiwa['danceability']-0.1) <= feature['danceability'] <= (reiwa['danceability']+0.1) and \
   (reiwa['loudness']-1) <= feature['loudness'] <= (reiwa['loudness']+1) and \
   (reiwa['energy']-0.1) <= feature['energy'] <= (reiwa['energy']+0.1):
		
    # 条件に合致した曲を取得
    match = sp.track(feature['id'])
		
    print(match['name'], "は、令和と同じくらい盛り上がる曲です。")

print('処理が終了しました。')
```

実行結果

```
長谷サンズ は、令和と同じくらい盛り上がる曲です。
バビロン天使の詩 は、令和と同じくらい盛り上がる曲です。
処理が終了しました。
```

ぼくが作ったとあるプレイリスト（100曲入り）からすべて検索し、`audio_features`がもつパラメータが令和に近い曲を探すプログラムです。

比較している箇所ではそれっぽい値を、範囲をもたせて比較するようにしました。

100曲のうち2曲ヒットしました。令和と同じくらい盛り上がるこの2曲（Spotify API調べ）なので、興味がおありの方はぜひ聴いてみていただきたいです。


### まとめ

今回は`audio_features`を紹介しました。

それぞれの値がどうやって算出されているのかは皆目見当も付きませんが、みなさんも遊べる機会があれば、自分の好きな曲をいろいろ見てみて、並べて比較するだけでもけっこうおもしろいとおもいますよ。