Spotifyでは、oEmbedの方法で、未ログインでも再生ができるWEB向けのiFrameプレイヤーをAPIから取得できる。これをNuxt.jsのプラグイン化する方法。
通常、iFrameのURLをHTMLに記述してプレイヤーを埋め込むが、そのiFrameの内容をJSON形式でも取得できる。
動作環境
通常のiFrame
<iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/25Wlc36nhO0sd8mNOQbOv1?utm_source=generator" width="100%" height="380" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"></iframe>
このようHTMLを埋め込むと、
と、表示される。
取得API
既出のiFrameのソースコードをこのAPIで取得可能
https://open.spotify.com/oembed?url=https%3A%2F%2Fopen.spotify.com%2Fplaylist%2F{id}
{id}
の部分をプレイリストのIDを指定する。
取得結果
{
html: "<iframe style="border-radius: 12px" width="100%" height="380" title="Spotify Embed: 昼の放送 #27" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" src="https://open.spotify.com/embed/playlist/25Wlc36nhO0sd8mNOQbOv1?utm_source=oembed"></iframe>",
width: 456,
height: 380,
version: "1.0",
provider_name: "Spotify",
provider_url: "https://spotify.com",
type: "rich",
title: "昼の放送 #27",
thumbnail_url: "https://mosaic.scdn.co/300/ab67616d0000b273115c265fae60f66103a965c9ab67616d0000b2736dba235db4ccbec24606f0d9ab67616d0000b273bf6bcb4f1d2c4c49e67d6999ab67616d0000b273d6c059712a4916f1b278405a",
thumbnail_width: 300,
thumbnail_height: 300
}
実装的には、プレイリストのタイトル、サムネイル画像のURLを取得できる点が便利。
プラグイング化
import { Plugin } from '@nuxt/types'
import { NuxtHTTPInstance } from '@nuxt/http'
class SpotifyEmbed {
http: NuxtHTTPInstance
constructor(http: NuxtHTTPInstance) {
this.http = http
}
/**
* iFrameを取得
* @param id spotifyのプレイリストのid
* @returns
*/
public async get(id: string): Promise<any> {
try {
return await this.http.$get(
`https://open.spotify.com/oembed?url=https%3A%2F%2Fopen.spotify.com%2Fplaylist%2F${id}`
)
} catch (error) {
console.log('response error', error)
}
}
}
export const spotifyEmbedPlugin: Plugin = (context, inject) => {
const spotifyEmbed = new SpotifyEmbed(context.app.$http)
inject('spotifyEmbed', spotifyEmbed)
}
export default spotifyEmbedPlugin
declare module '@nuxt/types' {
interface Context {
$spotifyEmbed: SpotifyEmbed
}
}
.vueファイルからはこういう形で使う
<script lang="ts">
...
import { useSpotify } from '@/composables/spotifyState'
import {
defineComponent,
ref,
useContext,
} from '@nuxtjs/composition-api'
...
export default defineComponent({
const { app } = useContext()
...
const spotifyId = '25Wlc36nhO0sd8mNOQbOv1'
...
setup(props) {
...
async created() {
const searchResult = await app.$spotifyEmbed.get(spotifyId)
}
...
}
}
async
を宣言しているメソッド内で、await
で実行結果を受け取ることができる。後は、ref
宣言した変数にhtml
部分を入れて、テンプレート内に表示することが可能。
const spotifyIFrame = ref({ html: '' })
const searchResult = await app.$spotifyEmbed.get(spotifyId.value)
spotifyIFrame.value = searchResult
Vuetifyを使ってテンプレートに表示する例
<div v-html="spotifyIFrame.html"></div>
ref
で初期化する際に、html
を空白にすることで、レンダリングのエラーを回避している