背景
以下のQiitaの記事を読み、私もSpotify APIを使ってみたくなりました😃
Spotify-Extension-A
完成したサービスがこちらです。
たった3step
で、あなただけのプレイリストが作成可能です😏
demo pic.twitter.com/05rj7TRLwq
— playtag551 (@playtag551) February 23, 2021
実装したかった機能
Spotifyは素晴らしいサービスです!!私も愛用しています😊
ただ、私が思うSpotifyのかゆい所、それは、
大好きなアーティストだけでプレイリストを作って欲しい♫
アップテンポな曲ばかりでプレイリストを作って欲しい♫
ということです。
Spotifyではユーザーにおすすめのプレイリストが自動的に作成されます。( Daily MixやDiscover Weekly ) これは、ユーザが過去に試聴したトラック情報を用いて作成されていると思われます。個人的な感想としては、大好きな曲から、まぁまぁ好き、チャレンジ枠と曲が分散しているな
、といった印象です。好きな曲ばかりを聞きたい私としては、探索的な効果
はあまり必要ではないのです。
ということで、前述した機能を実装しました。
動作フロー
上記のデモ動画の場合の、大まかな動作フローは以下の図のようになっています。
お気に入りのアーティストから、プレイリストを作る場合であれば、
最終的に対象となる曲数は1,500程度
となります。(API制限に引っかからないうちであれば。)
そこから、ユーザが選択した曲調に応じたロジックを走らせて曲を厳選し、プレイリスト上限数(たぶん100)を超えるようであれば、ランダムに80曲
を抽出するようにしています。
苦労した点
- 非同期処理
- APIを叩きまくるので、非同期処理が必須でした。
Promise.all
を利用しているのですが、リクエストが一つでもエラーになると失敗判定になってしまいます。特に、API制限で結構エラーが出てしまうので、エラー時でも{}のレスポンスを返却して、成功しているように見せかけることで、処理が継続するようにしました。また、リクエストにはランダムにsleep
を仕込んで負荷を分散させるようにしました。
- APIを叩きまくるので、非同期処理が必須でした。
- ランダム性を持たせる
- 固定値でアーティストの曲を取得してしまうと、毎回同じ曲が候補として選ばれてしまいます。それではつまらないので、
offset
(何番目から取得するか)をランダム
にずらすようにしています。(ユーザのフォローしているアーティストを取得するAPIだけこのパラメータがない...)また、リクエストの順番もシャッフルすることで、アーティストが偏りづらくなるようにしています。(これは特に、リクエストエラーが多発する場合に効果を発揮します)
- 固定値でアーティストの曲を取得してしまうと、毎回同じ曲が候補として選ばれてしまいます。それではつまらないので、
- ロジック
- 初めは、
曲の重複排除
をidベースで行っていたのですが、マーケットの違いなのか、同じ曲でも違うidが与えられている場合が多かったです。現在は曲名&アーティスト名をkeyにして重複排除を行っています。また、ある曲のなんとかバージョン
とかInstrumental版
とかSpotifyだと多いので、正規表現で排除しています。(個人的好みです。) - 思ったより、
曲の特徴成分
が微妙だなっていうのがありました。結局、ロジックで利用しているのはenergy
,tempo
,valence
の3つだけです。(なんでワンパンマンのOPよりサイレントマジョリティーの方がloudness
大きいのじゃ...)
- 初めは、
acousticness: 0.261
danceability: 0.583
duration_ms: 265827
energy: 0.952
instrumentalness: 0
key: 1
liveness: 0.314
loudness: -2.491
mode: 1
speechiness: 0.0797
tempo: 123.015
time_signature: 4
valence: 0.81
# 各特徴について
https://www.wizard-notes.com/entry/music-analysis/spotify-api-audio-features
- UI
github
一応、githubに置いておきます。
Spotify Developer トークンの作成・callbackエンドポイントの登録を行えば、
docker-compose up
で動作します✨
.
├── Dockerfile
├── README.md
├── docker-compose.yml
├── .env # spotify の developer tokenなどを記述するファイル(別途作成)
├── main
│ ├── index.ts # nodeのサーバー
│ └── public
│ ├── index.html
│ └── statics
│ ├── css
│ │ ├── common.css # scssをコンパイルしたもの
│ │ └── common.scss
│ ├── img
│ └── js
│ └── common.js
├── package-lock.json
├── package.json # 必要なライブラリやコマンドを記述したもの
├── .prettierrc.json # フォーマット関連
├── .eslintrc.json # フォーマット関連
├── tsconfig.json # フォーマット関連
└── tslint.json # フォーマット関連
終わりに
まだまだ自作のプレイリストには勝てませんが、大好きなアーティストの知らない曲を発掘できていい感じです!!
console.log()
をいくつか仕込んでいるので、chromeなどで挙動を確認してみると面白いと思います😁 この曲、tempo:0.3なのかよ!みたいな笑
※ちなみに、
まだ、
3点1点妥協している部分があるので、確認してみてください笑
の答えは
- 初期状態で
range slider
の中央をクリックすると、ポップアップが一番左に出てしまう <- 初期の中央クリックがjqueryでchange判定されないため... toggle button
がORの時のマークを✔︎
ではなくて||
にしたい <- かなりむずいアクセストークンが期限切れでもAPIのローディングマークが(永遠に)出てしまう。