本記事について
この記事では、Javaを使用しSpotify Web APIを叩いて、楽曲情報の取得やプレイリストへの追加をしてみた方法を紹介します。
【 Spotify Web APIとは 】
音楽ストリーミングサービスで有名なSpotifyが提供しているAPIです。
Spotify Web APIによって下記の情報等が取得できます。
- アルバム情報
- アーティスト情報
- トラック(楽曲)情報
- プレイリスト情報
Spotify Web API
You can use Spotify's Web API to discover music and podcasts, manage your Spotify library, control audio playback, and much more.
サンプルコード
今回紹介する機能を実装したサンプルとして、GithubのURLを下記に記載します。
実装について
- 言語
- Java SE
- エディタ
- VSCode
- Webサーバー(サーブレットコンテナ)
- Jetty
認証
APIを使用するにあたってSpotify Web APIの認証周りを順に見ていきます。
1.1 codeの取得
アクセストークン
を生成するためのcode
の取得方法について解説します。
下記のクエリを持ったURLにアクセスして、持っているSpotify アカウントでログインします。
// AUTHORIZATION URL
https://accounts.spotify.com/authorize
// QUERY PARAMETER
client_id="生成したクライアントID"
response_type="code"
redirect_uri="ログイン後に遷移したいURI"
state="SecureRandom()を使用"
scope="スコープの指定"
Javaでクエリを持たせたAUTHORIZATION URLを返すメソッドはこんな感じで作りました。
// ※それぞれURLEncoderでutf-8にエンコードしています。
// 環境変数の読み込み準備
Dotenv dotenv = Dotenv.configure().load();
// 環境変数からの読み込み
private final String clientId = dotenv.get("CLIENT_ID");
private final String clientSecret = dotenv.get("CLIENT_SECRET");
private final String redirectUri = dotenv.get("REDIRECT_URI");
private final String authorizeUrl = dotenv.get("AUTHORIZE_URL");
private final String[] scope = {
"playlist-read-private",
"playlist-modify-private",
"playlist-read-collaborative",
"playlist-modify-public",
"user-read-email",
"user-read-private",
"user-modify-playback-state",
"user-read-playback-state",
"user-read-currently-playing",
"user-read-recently-played",
"user-read-playback-position",
"user-top-read"
};
public String getAuthorizationUrl() throws UnsupportedEncodingException {
return String.format("%s?client_id=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s", this.authorizeUrl,
this.clientId, URLEncoder.encode(this.redirectUri, "utf-8"), String.join(" ", this.scope),
new SecureRandom());
}
URLにアクセスして、Spotifyアカウントでログインするとアクセストークン
を生成するためのcode
が取得できます。
Ex.)
https://my-domain.com/callback?code=NApCCg..BkWtQ&state=34fFs29kd09
※リダイレクトURIをhttp://localhost:8080/〇〇/callback
そして設定した場合、サーブレットでは下記の記述でcode
の取得が可能です。
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mashape.unirest.http.exceptions.UnirestException;
@WebServlet("/〇〇/callback")
public final class CallbackServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// callbackからのレスポンス(code)を取得
String code = (request.getParameter("code") == null) ? "" : (String) request.getParameter("code");
}
}
1.2 アクセストークンの取得
楽曲情報の取得やプレイリストの作成等に必要なアクセストークン
の取得方法について解説します。
下記のヘッダパラメーター、リクエストボディを持たせて、POSTリクエストを送るとアクセストークンが取得できます。
// API ENDPOINT
https://api.spotify.com/v1
// HEADER PARAMETER
Authorization: Basic <base64 encoded クライアントID:クライアントシークレットID>
Content-Type: application/x-www-form-urlencoded
// REQUEST BODY PARAMETER
grant_type="authorization_code"
code="先ほど取得したcode"
redirect_uri="ログイン後に遷移したいURI"
Javaでアクセストークンを生成するメソッドはこんな感じで作りました。
// ※リクエストボディはそれぞれURLEncoderでutf-8にエンコードしています。
private String accessToken;
public void crateAccessToken() throws UnirestException, UnsupportedEncodingException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://accounts.spotify.com/api/token"))
.setHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString((clientId + ':' + clientSecret).getBytes(StandardCharsets.UTF_8)))
.setHeader("Content-Type", "application/x-www-form-urlencoded")
.POST(BodyPublishers.ofString(String.format("grant_type=%s&code=%s&redirect_uri=%s", URLEncoder.encode("authorization_code", "UTF-8"), URLEncoder.encode(getCode(), "UTF-8"), URLEncoder.encode(redirectUri, "UTF-8"))))
.build();
try {
// リクエストを送信
var response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
// レスポンスボディからaccess_tokenの取得
JSONObject json = new JSONObject(response.body());
// アクセストークンの設定
accessToken = json.getString("access_token")
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
楽曲検索
キーワードを使用して、実際に楽曲検索する方法を解説します。
下記のクエリで検索を行います。
// URL
https://api.spotify.com/v1/search
// Query
q: String (検索キーワード)
type: track(楽曲)
Ex.)
https://api.spotify.com/v1/search?q=キーワード&type=&type=track
Javaで楽曲検索するメソッドはこんな感じで作りました。
// ※このメソッドでは、検索結果を{アルバム画像URL、アルバム名、アーティスト名、トラック名、トラックID}のJSONで返しています。
// ※クエリはそれぞれURLEncoderでutf-8にエンコードしています。
public String search(String keyword) throws UnsupportedEncodingException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiEndpoint
+ String.format("/search?q=%s&type=%s&limit=5", keyword, URLEncoder.encode("track", "utf-8"))))
.setHeader("Authorization", "Bearer " + this.accessToken)
.setHeader("Content-Type", "application/json")
.GET()
.build();
// レスポンスの格納変数
StringBuilder builder = null;
try {
// リクエストを送信
var response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
// レスポンスボディからaccess_tokenの取得
JSONObject json = new JSONObject(response.body());
// tracksの取得
JSONObject tracks = json.getJSONObject("tracks");
// tracksの中の楽曲データの取得
JSONArray data = tracks.getJSONArray("items");
// レスポンスの生成準備
builder = new StringBuilder();
// JSON形式でレスポンスデータを構成
builder.append("{\"data\":");
builder.append('[');
for (int i = 0; i < data.length(); i++) {
builder.append('{');
builder.append("\"album_image_url\":\"").append(
data.getJSONObject(i).getJSONObject("album").getJSONArray("images").getJSONObject(0).get("url"))
.append("\",");
builder.append("\"album_name\":\"").append(data.getJSONObject(i).getJSONObject("album").get("name"))
.append("\",");
builder.append("\"artist_name\":\"")
.append(data.getJSONObject(i).getJSONArray("artists").getJSONObject(0).get("name"))
.append("\",");
builder.append("\"track_name\":\"").append(data.getJSONObject(i).get("name")).append("\",");
builder.append("\"track_id\":\"").append(data.getJSONObject(i).get("uri")).append("\"");
builder.append("}");
if (i != data.length() - 1) {
builder.append(",");
}
}
builder.append(']');
builder.append('}');
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
// JSON形式作ったレスポンスデータを返す
return builder.toString();
}
プレイリストへの追加
指定のプレイリストのIDを使用して、プレイリストへの楽曲追加する方法を解説します。
下記のクエリで検索を行います。
// URL
https://api.spotify.com/v1/playlists/指定のプレイリストID/tracks
// HEADER PARAMETER
Authorization: Bearer アクセストークン
Content-Type: application/json
// Query
uris: JSONObject (指定のプレイリストへ追加したいトラックのIDの入ったJSON配列を持つJSONオブジェクト)
=> {
"uris": [
"string"
]}
Javaでプレイリストに楽曲追加するメソッドはこんな感じで作りました。
public String addTrack(JSONObject uris) throws UnsupportedEncodingException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiEndpoint + String.format("/playlists/%s/tracks", dotenv.get("PLAYLIST_ID"))))
.setHeader("Authorization", "Bearer " + this.accessToken)
.setHeader("Content-Type", "application/json")
.POST(BodyPublishers.ofString(uris.toString()))
.build();
StringBuilder builder = null;
try {
// リクエストを送信
var response = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
// レスポンスボディからレスポンスの取得
JSONObject json = new JSONObject(response.body());
builder = new StringBuilder();
builder.append('{');
builder.append("\"snapshot\":").append(json).append("");
builder.append('}');
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return builder.toString();
}
最後に
本記事では、JavaでSpotify Web APIを使用して楽曲情報とプレイリストへの楽曲追加方法を紹介しました。
JavaでAPIを叩くことがなかった私からするとなかなか興味深いものでした。
アウトプットがてらに別言語でも実装してみて見るものいいかもしれないですね。
参考文献
※Servlet等についてはここでは詳しく述べてませんが、サンプルコードを参考にしていただければと思います。