Spotify APIを使い曲の再生機能を実装する
開発環境
- macOS
- VSCode
- Rails 7.1.3.3
- ruby-3.2.3
- PostgreSQL 16.2
行いたいこと
-
Spotify API
を使い曲の再生機能を実装する。
Spotify APIを利用するにあたって...
・Spotifyのアカウントを作成する。
・Dashboardからアプリの登録
とCLIENT ID
とCLIENT SECRET ID
の取得をする。
・取得したIDを環境変数
として.envファイル
に記載する。
こちらの手順で行いました⇩
Gem をインストールする
・以下を追記しbundle install
gem 'rspotify'
環境変数を読み取れるように記載する
・.envファイル
に記載したCLIENT ID
とCLIENT SECRET ID
を読み取れる様に正しく記載。
require 'rspotify'
RSpotify.authenticate(ENV['SPOTIFY_CLIENT_ID'], ENV['SPOTIFY_SECRET_ID'])
gem 'dotenv-rails'がなければインストール
・.envファイル
を簡単に読み取るため
・以下を追記しbundle install
gem 'dotenv-rails'
テーブル・カラム・モデルを追加、記載する
・曲の表示方法は開催されたライブイベント一覧
⇨参加したアーティスト一覧
⇨披露した曲一覧
のように
遷移させたい。
・live_event
,artist
,music
,live_events_artist
のテーブル
・カラム
・モデル
を追加する。
class LiveEvent < ApplicationRecord
has_many :live_events_artists
has_many :artists, through: :live_events_artists
has_many :musics
end
class Artist < ApplicationRecord
has_many :live_events_artists
has_many :live_events, through: :live_events_artists
end
class Music < ApplicationRecord
belongs_to :artist
belongs_to :live_event
end
class LiveEventsArtist < ApplicationRecord
belongs_to :live_event
belongs_to :artist
end
コントローラーを記載する
・ライブイベントの一覧表示 / 指定されたライブイベントの表示
class LiveEventsController < ApplicationController
def index
@live_events = LiveEvent.all
end
def show
@live_event = LiveEvent.find(params[:id])
end
end
・ライブイベントにアーティストの一覧表示 / 曲の一覧表示 / 指定したアーティストと曲の表示
class MusicsController < ApplicationController
# アーティストを取得、ライブイベントを取得
def index
@artist = Artist.find(params[:artist_id])
@live_event = LiveEvent.find(params[:live_event_id]) if params[:live_event_id].present?
# 特定のライブイベントに関連する曲のみを取得、ライブイベントが指定されていない場合は、アーティストの全ての曲を取得
if @live_event
@musics = @artist.musics.where(live_event_id: @live_event.id)
else
@musics = @artist.musics
end
# 曲の情報を整形
@musics = @musics.map do |music|
{
name: music.name,
artist: music.artist_name,
id: music.spotify_track_id,
live_event_id: music.live_event_id
}
end
end
# アーティストを取得、Spotify track IDで曲を検索
def show
@artist = Artist.find(params[:artist_id])
@music = Music.find_by(spotify_track_id: params[:id])
end
end
viewファイルを記載する
・ライブイベントを取得しリンクで一覧表示(装飾は省略)
<h1>開催ライブ一覧</h1>
<% @live_events.each do |live_event| %>
<div>
<%= link_to live_event_path(live_event), class: 'btn btn-slash' do %>
<span><%= live_event.name %></span>
<% end %>
</div>
<% end %>
・アーティストを取得しリンクで一覧表示(装飾は省略)
<h4><%= @live_event.name %></h4>
<% if @live_event.artists.any? %>
<% @live_event.artists.each do |artist| %>
<%= link_to artist_musics_path(artist, live_event_id: @live_event.id), class: 'btn btn-slash' do %>
<span><%= artist.name %></span>
<% end %>
<% end %>
<% else %>
<p>アーティストは登録されていません。</p>
<% end %>
・曲を取得しリンクで一覧表示(装飾は省略)
<h4><%= @artist.name %></h4>
<% if @musics && @musics.any? %>
<% @musics.each_with_index do |music, index| %>
<%= link_to artist_music_path(@artist, music[:id], live_event_id: params[:live_event_id])class:'text-decoration-none text-dark d-flex align-items-center w-100' do %>
<h5 class="mb-0 me-3 flex-grow-1">
<%= "#{index + 1}. #{music[:name]}" %>
</h5>
<% end %>
<% end %>
<% else %>
<div class="alert alert-warning" role="alert" style="background-color: #f8f9fa;background-colortransparent;">
音楽が見つかりませんでした。
</div>
<% end %>
・曲の再生ページ(Spotify 埋め込みプレイヤー)
<iframe src="https://open.spotify.com/embed/track/<%= @music.spotify_track_id %>"
width="300"
height="380"
frameborder="0"
allowtransparency="true"
allow="encrypted-media"
</iframe>
routes.rbの記載
・適宜必要なルートを記載する。
# artistsリソースの中に musicsリソースをネストする
resources :artists do
resources :musics, only: [:index, :show]
end
# アーティストごとに関連する音楽に対してアクセスするルート(開催ライブ一覧⇨アーティスト)
# 限定的なルーティング
resources :musics, only: [:index, :show]
# (アーティスト⇨曲一覧⇨曲の再生)
# live_eventsリソースの中に musicsリソースをネストする
resources :live_events, only: [:index, :show, :new, :create] do
resources :musics, only: [:index, :show]
end
# ライブイベントごとに関連する音楽の一覧に対してアクセスするルート
挙動の確認
以上でSpotify APIを使用した曲の再生機能の実装は完了です。
本番環境の場合は環境変数を記載(Herokuの場合)
.env
に記載したCLIENT ID
とCLIENT SECRET ID
をHeroku側にも設定する
・Herokuのダッシュボードから、設定
⇨設定変数
⇨鍵
と価値
に値を入力し追加
・鍵
と価値
に値を入力し追加
・環境変数
を記載(.env
が参照できるように正しく記載)
・今回は以下の2つを登録しました。
[鍵]SPOTIFY_CLIENT_ID
[価値]取得したCLIENT ID
[鍵]SPOTIFY_SECRET_ID
[価値]取得したCLIENT SECRET ID
データベースにライブイベント、アーティスト、曲を追加する流れ(Herokuのデータベース PostgreSQL)
・ライブイベントの作成 ⇨ アーティストの作成 ⇨ ライブイベントにアーティストを追加
INSERT INTO live_events (name, date, created_at, updated_at)
VALUES ('YOASOBI LIVE IN THE USA (2024/4/18.21)', '2023-08-10', NOW(), NOW());
↑ ↑
[登録したいライブイベント名] [データ追加年月日]
・アーティストの追加
INSERT INTO artists (name, created_at, updated_at)
VALUES ('YOASOBI', NOW(), NOW());
↑
[登録したいアーティスト名]
・ライブイベントにアーティストを追加
INSERT INTO live_events_artists (live_event_id, artist_id)
SELECT 100, id FROM artists WHERE name IN ('YOASOBI');
↑
[追加したいライブイベントID]
・YOASOBI LIVE IN THE USA (2024/4/18.21)
というライブイベントに YOASOBI
というアーティストが追加される。
・アーティストのidを取得 ⇨ Spotify_track_idの取得 ⇨ musicsテーブルに保存
・rails console
からアーティストのidを取得する。
artist_name = 'YOASOBI'
artists = RSpotify::Artist.search(artist_name)
if artists.any?
puts "アーティストが見つかりました:"
artists.each do |artist|
puts "アーティスト名: #{artist.name}, Spotify ID: #{artist.id}"
end
else
puts "アーティストは見つかりませんでした。"
end
・取得したアーティストのidで、アーティストのSpotify_track_id
を全曲取得する。
# RSpotifyでアーティストを検索
artist = RSpotify::Artist.find('取得したアーティストid')
if artist
puts "アーティスト名: #{artist.name}"
puts "曲一覧:"
albums = artist.albums(limit: 50)
albums.each do |album|
puts "アルバム名: #{album.name}"
tracks = album.tracks(limit: 50)
tracks.each do |track|
puts " 曲名: #{track.name}, Spotify ID: #{track.id}"
end
puts "-" * 100
end
else
puts "曲は見つかりませんでした。"
end
・musicsテーブルに保存する
INSERT INTO musics (name, spotify_track_id, artist_id, artist_name, live_event_id, created_at, updated_at)
VALUES
('[曲名]', '[spotify_track_id]', [artist_id], '[artist_name]', [live_event_id], NOW(), NOW());
以上です。
Discussion