Skip to content

Instantly share code, notes, and snippets.

@takemikami
Created June 2, 2023 15:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takemikami/fe148d8a474a598115399a3b82636fbd to your computer and use it in GitHub Desktop.
Save takemikami/fe148d8a474a598115399a3b82636fbd to your computer and use it in GitHub Desktop.
音響特徴に寄せたアイマス楽曲のプレイリストを登録するスクリプト
# 音響特徴に寄せたアイマス楽曲のプレイリストを登録するスクリプト
#
# 前提:
# 以下の環境変数を設定(.envファイルに記載)
# SPOTIPY_CLIENT_ID: spotify web apiのID
# SPOTIPY_CLIENT_SECRET: spotify web apiのシークレットキー
# TARGET_PLAYLIST_ID: 更新するプレイリストのID
# 以下の依存ライブラリをインストール
# pip install spotipy
# pip install python-dotenv
# pip install numpy
# pip install pandas
#
# 実行方法:
# python imaspotify.py [ブランド名] [音響特徴]
# 例) シャニマスのenergyに寄せた楽曲をプレイリストに登録する
# python imaspotify.py ShinyColors energy
import json
import math
import os.path
import sys
import time
import numpy as np
import pandas as pd
import spotipy
from dotenv import load_dotenv
from spotipy.oauth2 import SpotifyClientCredentials, SpotifyOAuth
load_dotenv()
features = [
'danceability',
'energy',
'key',
'loudness',
'mode',
'speechiness',
'acousticness',
'instrumentalness',
'liveness',
'valence',
'tempo'
]
def get_spotify_client():
return spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials())
def get_spotify_oauth():
scope = "playlist-modify-private"
os.environ["SPOTIPY_REDIRECT_URI"] = "http://localhost:8080/"
spotify = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
return spotify
def get_features_fromplaylist(spotify, playlist_id):
filename = f"playlist_features_{playlist_id}.json"
if os.path.exists(filename):
with open(filename, "r") as f:
items = json.loads(f.read())
return items
time.sleep(10)
items = []
# get tracks from playlist
for t in range(10):
offset = 100 * t
results = spotify.playlist_items(playlist_id, offset=offset)
items.extend(results['items'])
if results["offset"] + results["limit"] > results["total"]:
break
# get features from tracks
id_idx_map = {e['track']['id']: i for i, e in enumerate(items)}
number_of_sublist = math.ceil(len(id_idx_map.keys()) / 30)
list_set = np.array_split(list(id_idx_map.keys()), number_of_sublist)
counter = 0
for t, l in enumerate(list_set):
res2 = spotify.audio_features(l)
for e in res2:
items[counter]["features"] = e
counter += 1
with open(filename, "w") as f:
f.write(json.dumps(items))
return items
def convert_to_dataframe(items):
columns = ['id', 'name', 'artist', *[*features]]
data = [
[
e['track']['id'],
e['track']['name'],
', '.join([a.get('name', '') for a in e['track'].get('artists', [])]), # [0].get('name', ''),
*[*[e['features'][f] for f in features]]
]
for i, e in enumerate(items)
]
df = pd.DataFrame(data, columns=columns)
return df
def get_feature_dataframe(spotify, brand: str="all") -> pd.DataFrame:
playlists = []
if brand == "all" or brand == "765":
playlists.append('3mWR84C5UUyoJIf6d2CF9R')
if brand == "all" or brand == "ShinyColors":
playlists.append('0vKD0u46kcm0PxIzzmbBD9')
if brand == "all" or brand == "CinderellaGirls":
playlists.append('1OL47KFL8HGi5OtGdsd0Tt')
if brand == "all" or brand == "MillionLive":
playlists.extend([
'328b2gee1LdKta0gurnDES', # Unit
'66JxoB4JzYeITPyBZa2UP2', # Solo
])
if brand == "all" or brand == "SideM":
playlists.append('5KAAHcj9bJV2rkuR8x4FUn')
df_list = list()
for playlist_id in playlists:
items = get_features_fromplaylist(spotify, playlist_id)
df_list.append(convert_to_dataframe(items))
return pd.concat(df_list, ignore_index=True).drop_duplicates()
def get_feature_topK(spotify, feature, brand="all", k=20):
df = get_feature_dataframe(spotify, brand)
df_feature = df.sort_values(feature, ascending=False).head(k)
return df_feature
def update_playlist(spotify_oauth, playlist_id, track_ids):
items = [f"spotify:track:{id}" for id in track_ids]
spotify_oauth.playlist_replace_items(playlist_id, items)
if __name__ == '__main__':
if len(sys.argv) < 3:
print(f"usage: python imaspotify.py [all|765|ShinyColors|CinderellaGirls|MillionLive|SideM] [{'|'.join(features)}]")
exit(1)
brand = sys.argv[1]
feature = sys.argv[2]
# get tracks
spotify = get_spotify_client()
df = get_feature_topK(spotify, feature, brand)
print(df[["name", "artist", feature]])
# update playlist
playlist_id = os.environ["TARGET_PLAYLIST_ID"]
spotify_oauth = get_spotify_oauth()
update_playlist(spotify_oauth, playlist_id, df["id"].values)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment