Spotifyで現在再生中の曲をAWS IoTボタンでプレイリストに追加する

Spotifyで現在再生中の曲をAWS IoTボタンでプレイリストに追加する:

この記事は、ケーシーエスキャロット Advent Calendar 2018 の16日目の記事です。

音楽を聴きながら仕事をしていると、ふと気になる曲が流れることがありますよね。

私はSpotifyを使用しているのですが、曲名を確認する程度ならSpotMenuが便利ですが、

プレイリストに登録する作業は、毎回Spotifyアプリを開いてポチポチしなければなりません。

仕事中には結構な手間ですし、集中が途切れる要因になります。


概要

そこで、AWS Lambdaを使って現在再生中の曲をプレイリストに追加するコードを書き、

IoTボタンと組み合わせて、1プッシュで実行出来るようにしたいと思います。

Spotifyのアカウントは取得済みを前提とします。

また、ローカルの開発端末はmacを想定としていますので、それ以外の方は適宜読み替えてください。


SpotifyのAPIについて

SpotifyのAPIは、検索やトラック情報取得といったグローバルなAPIは

Client IDとClient Secretを使ってトークンを取得するだけで使用出来るのですが、

自分が今再生している曲を取得するようなプライベートな情報を扱うAPIは、OAuth認証が必要です。

つまり、インタラクティブな処理が必要ということになります。


どう実現するか

SpotifyのAuthorization Code Flowを見ると、
GET https://accounts.spotify.com/authorizeで返却されたログイン画面に、

ユーザー名とパスワードでログインし、リダイレクト先URLのパラメータの値を取得する必要があります。

ここの部分をLambdaで実現するために、Lambda上でseleniumを使い、headless chromeを動かすことにします。


手順

  • Client IDとClient Secretの取得
  • Redirect URIsの設定
  • 登録先プレイリストの作成とIDの取得
  • Lambdaの設定

    • serverless-chromiumのインストール
    • chromedriverのインストール
    • Redirect URIsの設定
    • 登録先プレイリストの作成とIDの取得
    • lambda_function.pyの作成


Client IDとClient Secretの取得

Spotify for Developersからログインし、DashboardページにあるCREATE A CLIENT IDから、必要な情報を入力して作成します。


  • App or Hardware Name

    • 適当で大丈夫です

  • App or Hardware Description

    • 適当で大丈夫です

  • What are you building?

    • 適当で大丈夫です、I don't knowにでもチェック付けておきましょう
次ページで3つのチェックボックスにチェックをつけ、SUBMITをクリックすると、

作成したアプリケーションのページに遷移します。

SHOW CLIENT SECRETをクリックし、Client IDとClient Secretを控えておきましょう。


Redirect URIsの設定

先ほどのアプリケーション画面にあるEDIT SETTINGSを開き、
Redirect URIshttp://localhostを記載し、ADDしてからSAVEしましょう。

ここに登録されたuriのみが、後ほど出てくる認証時のリダイレクト先のパラメータで指定出来ます。


登録先プレイリストの作成とIDの取得

Lambda実行時に登録するプレイリストをアプリなどから作成します。

IDの取得方法については、以下の通りです。

途中ログイン画面が入った場合は適宜ログインしてください。

  1. Spotify for Developersのコンソールからプレイリスト取得APIを開く
  2. OAuth TokenのGET TOKENをクリック

  3. Required scopes for this endpoint:に記載されているplaylist-read-privateにチェック

  4. REQUEST TOKENをクリック

  5. TRY ITをクリック
  6. 出力された結果から、対象プレイリストの"id"の値を取得


Lambdaの設定

今回は最終的にデプロイパッケージのサイズが50MB程になるため、コンソールからはソースが編集出来ません。

なので、ローカルでソースを編集し、zipファイルにしてS3にアップロードしたファイルを使用します。

Lambdaでheadless chromeを使用する方法については、AWS Lambda上のheadless chromeをPythonで動かすを参考にさせて頂きましたので、そちらをご参照ください。

こちらでは引用して記載します。


serverless-chromiumのインストール

mkdir -p bin/ 
curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-37/stable-headless-chromium-amazonlinux-2017-03.zip > headless-chromium.zip 
unzip headless-chromium.zip -d bin/ 
rm headless-chromium.zip 


chromedriverのインストール

curl -SL https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip > chromedriver.zip 
unzip chromedriver.zip -d bin/ 
rm chromedriver.zip 


必要なパッケージのインストール

現状、pip install spotipy -t ./でインストールすると、

current_user_playing_track()がないため以下のようにインストールします。

pip install --upgrade git+https://github.com/plamere/spotipy.git -t ./ 
pip install selenium -t ./ 


lambda_function.pyの作成

いよいよ本題です。

seleniumを使ってログイン処理をし、authorization_codeを取得した後、

それを使ってAPIからアクセストークンを取得し、現在再生中の曲をプレイリストに入れる処理になります。

from spotipy import Spotify 
from spotipy.oauth2 import SpotifyOAuth 
from urllib.parse import urlencode, urlparse, parse_qs, quote 
from selenium import webdriver 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.common.by import By 
 
AUTHORIZE_URL = 'https://accounts.spotify.com/authorize' 
CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxxxxx' 
CLIENT_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxx' 
LOGIN_USERNAME = 'xxxxxxxxxxxxxxxxxxxxxxx' 
LOGIN_PASSWORD = 'xxxxxxxxxxxxxxxxxxxxxxx' 
PLAYLIST_ID = 'xxxxxxxxxxxxxxxxxxxxxxx' 
SCOPE = 'user-read-currently-playing playlist-modify-public playlist-modify-private' 
LOCALHOST = 'http://localhost' 
 
def lambda_handler(event, context): 
 
    options = webdriver.ChromeOptions() 
    options.binary_location = './bin/headless-chromium' 
 
    # headlessで動かすために必要なオプション 
    options.add_argument('--headless') 
    options.add_argument('--disable-gpu') 
    options.add_argument('--window-size=1280x1696') 
    options.add_argument('--disable-application-cache') 
    options.add_argument('--disable-infobars') 
    options.add_argument('--no-sandbox') 
    options.add_argument('--hide-scrollbars') 
    options.add_argument('--enable-logging') 
    options.add_argument('--log-level=0') 
    options.add_argument('--single-process') 
    options.add_argument('--ignore-certificate-errors') 
    options.add_argument('--homedir=/tmp') 
    driver = webdriver.Chrome('./bin/chromedriver', chrome_options=options) 
 
    params = { 
        'client_id': CLIENT_ID, 
        'response_type': 'code', 
        'redirect_uri': LOCALHOST, 
        'scope': SCOPE 
    } 
 
    # ヘッドレスブラウザでログイン処理をし、アクセストークン生成に必要なcodeの値を取得する 
    driver.get('{}?{}'.format(AUTHORIZE_URL, urlencode(params, quote_via=quote))) 
    WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.ID, 'login-username'))) 
    driver.find_element_by_id('login-username').send_keys(LOGIN_USERNAME) 
    driver.find_element_by_id('login-password').send_keys(LOGIN_PASSWORD) 
    driver.find_element_by_id('login-button').click() 
    code = parse_qs(urlparse(driver.current_url).query).get('code')[0] 
 
    # アクセストークンの取得 
    so = SpotifyOAuth(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri=LOCALHOST, scope=SCOPE) 
    res_token = so.get_access_token(code=code) 
    access_token = res_token['access_token'] 
 
    # 現在再生中の曲を取得してプレイリストに登録する 
    sp = Spotify(auth=access_token) 
    track_info = sp.current_user_playing_track() 
    if track_info is None: 
        return 'No music is being played.' 
    response = sp.user_playlist_add_tracks(LOGIN_USERNAME, PLAYLIST_ID, [track_info['item']['uri']]) 
 
    return response 
あとは作成したリソースをzipファイルにし、S3に配置したURLをLambdaで指定して実行するだけです。

なお、AWS IoTボタンとの連携はこちらを参考に実施しました。


実行してみる

処理時間を計ってみると、スムーズに終わって約20秒弱かかったので、Lambdaのタイムアウト値を1分程度に設定しておくのが良さそうです。

また、メモリも128MBだと少々心許ないので192MBに設定しておくことをオススメします。


最後に

曲のラストで「この曲いい!」と思ってポチッと実行しても、登録が間に合わない可能性があるのがネックですが、それは今後の課題として改善出来たらなと思っています。

少しざっくりとした説明になってしまったところもあるので、質問等があればコメントお願いします。

それでは皆さま職場での良き音楽ライフをお過ごしください!

コメント

このブログの人気の投稿

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-04-30 23:37:32 RSSフィード2021-04-30 23:00 分まとめ(42件)

投稿時間:2023-02-05 02:09:04 RSSフィード2023-02-05 02:00 分まとめ(9件)