オタクの落書き(改)

オタクがぶつぶつ言うだけ

spotifyのAPIで遊ぶ:その2

いいぞ俺!やる気あるやん!!

続きです。

someone34o2.hatenablog.com

この前はプレイリストを渡した場合で何とか実現したので、コンソールに渡す引数がプレイリスト以外のリンクでも何となく吸収していい感じに動くようにするのが目標。

import sys
import re
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

# 見せられないよ
client_id = ''
client_secrtet = ''

credential = SpotifyClientCredentials(client_id, client_secrtet)

spotify = spotipy.Spotify(client_credentials_manager = credential)

# メイン処理
def main_func(_share_link):
    (kind, target_uri) = uri_getter(_share_link)
    _name_list, _id_list = get_track_id_list(kind, target_uri)

    cnt = 0
    for _track_id in _id_list:
        print(_name_list[cnt])
        try:
            track_features = spotify.audio_features(_track_id)
        except Exception as ex:
            print(ex)
            continue
        print(track_features[0])
        # track_analysys = spotify.audio_analysis(_track_id)
        # print(track_analysys) # 人類には早すぎた
        cnt = cnt + 1

# 対象リンクごとに対象とする曲の名前とidのリストを生成
def get_track_id_list(kind, uri):
    _uri_list = []
    _name_list = []
    if kind == 'playlist':
        targets = spotify.playlist_tracks(uri)
        for element in targets['items']:
            _uri_list.append(element['track']['id'])
            _name_list.append(element['track']['name'])
    elif kind == 'artist':
        targets = spotify.artist_top_tracks(uri)
        for element in targets['tracks']:
            _uri_list.append(element['id'])
            _name_list.append(element['name'])
    elif kind == 'track':
        target = spotify.track(uri)
        _uri_list.append(target['id'])
        _name_list.append(target['name'])
    elif kind == 'album':
        targets = spotify.album_tracks(uri)
        for element in targets['items']:
            _uri_list.append(element['id'])
            _name_list.append(element['name'])
    else:
        print('{} content is not suported.'.format(kind))

    return (_name_list, _uri_list)

# リンクからuriを生成する
def uri_getter(share_link):
    _link = re.split('[/?]', share_link)
    # [0] = https, [1] = '', [2] = open.spotify.com
    _kind = _link[3]
    _link[2] = 'spotify'
    return (_link[3], ':'.join(_link[2:5]))


# モジュール呼び出し時
if __name__ == '__main__':
    _arg_list = sys.argv

    if len(_arg_list) == 1:
        print('input share link of spotify content')
        exit()

    main_func(_arg_list[1])

とは言いつつも一番癖があったのがプレイリストだったのでそう苦労しなかった。アーティストを対象とした場合に取得できる情報はいくつかに限られており、アルバム一覧か流行りの曲(top_tracks)が使えそうだった。まあアルバム一覧で取得した全アルバム対象にアルバム形式と同じ処理をすれば実質全曲なんだけど、まあめんどかったので…。すぐにタプルに逃げるのをやめなさ~~~い!!

以下それぞれの実行結果。プレイリストは昨日やったしええやろ…(数多くなるし)

f:id:someone34o2:20210908230415p:plain
アーティスト単位:https://open.spotify.com/artist/0eic2NIS2q4R4jZpKSH7cr?si=3f70320c4657472f

バニラのテンポ流石に早すぎやろ!!倍で拍とってそう。ハミダシモノってメジャー(mode=1)なのか…(ガバガバ音感)

f:id:someone34o2:20210908230617p:plain
アルバム単位:https://open.spotify.com/album/4LQVlXzxqW7leT6P0jYLnS?si=db87f0abe22f49da

アリアドネがちゃんと3拍子だけどwallまで3になってる。それは流石に嘘では?

f:id:someone34o2:20210908230642p:plain
曲単位:https://open.spotify.com/track/6orDsQsMy7BaqGoRWw3fVN?si=342115c051de47e0

"acousticness"が0.000124だったので面白かった。それはそう。

ところでコードをちゃんと読んだ方には気になる部分があったかと思います。

        # track_analysys = spotify.audio_analysis(_track_id)
        # print(track_analysys) # 人類には早すぎた

ここなんですが、出力させてみたら1曲当たりの情報量が余りにもえぐかった。ざっと見た感じ、以下のkeyに対して更に辞書がぶら下がっている感じ。

['meta', 'track', 'bars', 'beats', 'sections', 'segments', 'tatums']

  • meta:OSがどうとかかかった時間がどうとか。多分分析を実行した環境でしょう。まあ分かる。
  • track:ここからすでにヤバい、というか一番ヤバいかもしれない。特にcodestring, echoprintstring, rhythmstringとかいう要素がヤバい。現代版「ふっかつのじゅもん」みたいになってる。まさか曲の該当の情報を全部文字列にエンコードしたんか…?
  • bars, beats, tatums:いずれも{'start': 1.71706, 'duration': 1.85043, 'confidence': 0.397}みたいなのがずっと続く。barsが小節と訳せることや、雰囲気的にも曲を何らかの単位で分割してそうなのは分かる。
  • sections:上のやつらに似ていはいるんだが要素が増えている。sectionsにはloudness, tempo, keyなど見覚えのある単語が。おそらく区間ごとにその情報を分析したものの集合かと。区間数が多すぎるけど見てみたら面白いかもしれない。
  • segments:これも上のと同じ感じ。増えてるのはloudness_xxx(start, maxなど)と、リストのpitchesとtimbre(音色)。また区間ごとに情報を出しているのは分かる。配列の要素は面白そうだけど、辞書じゃなくて配列なので、どんな意味のある値か分からなくて詰み。元気があったらドキュメントひっくり返して探してみる(やらない)。

とまあちょっと掘り進めるには骨が折れそうな感じでした。featuresの内容の元になる細かい情報がanalysysなのかなと推測している。何かご存じの方いたらご一報ください。とりあえずは大人しくfeaturesの方を見やすい形にあーだこーだすることを次の目標としていきます。