发布于 2026-01-06 4 阅读
0

如何在 Next.js 中使用 Spotify API

如何在 Next.js 中使用 Spotify API

我的网站上有一个统计页面,展示了许多内容,例如我的 Dev.to 博客统计数据、GitHub 存储库数量和 Spotify 统计数据,我们将讨论如何在您的梦想项目中实现这些统计数据。

目录

预览

我在 Spotify 上最喜欢的 5 首歌曲

我在 Spotify 上最喜欢的 5 位艺术家

当我没有播放任何歌曲时

当前播放歌曲

创建 Spotify 应用

首先,我们需要在Spotify上创建一个应用程序。

  • 前往Spotify 开发者控制面板
  • 使用 Spotify 帐户登录登录
  • 点击“创建应用”
  • 填写名称和描述,然后点击“创建”。 创造
  • 请将您的客户端 ID 和密钥保存在您的…….env.local
  • 点击右上角的“编辑设置”http://localhost:3000/callback ,添加回调URL,然后点击“保存”编辑设置

一切就绪。现在我们来谈谈身份验证方面的内容。

使用身份验证refresh_token

我们采用了多种身份验证方式,refresh_token因为我们只想进行一次身份验证。您可以在这里了解有关授权的信息。

授权码流程

授权码

如上图所示,除了scopes之外,我们已经拥有了所有东西。scopes 定义了我们需要从 Spotify API 获取哪些内容。

为此,我们需要一个url向 Spotify 发送以下参数的工具:

  • response_type应该是code(如图所示)
  • redirect_uri回调 URL 与您在 Spotify 控制面板中输入的 URL 相同
  • client_id:你的项目的client_id
  • scope你可以在这里阅读相关内容。

我们需要获取用户的热门统计数据和当前播放的歌曲。为此,我们需要使用 `<scope>` 和 ` <scope>`user-top-readuser-read-currently-playing实现。您可以根据需要添加任意多个作用域,并用加号 ("+") 分隔。因此,现在我们的 URL 看起来像这样(请输入您的项目名称client_id):

# URL

https://accounts.spotify.com/authorize?client_id=bda10cd719564898818245d97727de7e&response_type=code&redirect_uri=http://localhost:3000/callback&scope=user-read-currently-playing+user-top-read 
Enter fullscreen mode Exit fullscreen mode

现在在浏览器中输入网址,然后按回车键。授权后,您将被重定向回您的浏览器redirect_uri。网址中有一个code查询参数。请将此值保存下来,因为我们将在下一步中用到它。

# code
http://localhost:3000/callback?code=CDxRCu......NLdsM
Enter fullscreen mode Exit fullscreen mode

得到refresh_token

完成以上步骤后,现在我们需要进行refresh_token身份验证。您需要生成一个包含之前获取的客户端 ID客户端密钥的 Base64 编码字符串。您可以使用此在线工具进行编码。格式应与此完全相同client_id:client_secret

您的网址应该类似于这样 -

# demo url to get "refresh_token"

curl -H "Authorization: Basic <base64 encoded client_id:client_secret>" -d grant_type=authorization_code -d code=<code> -d redirect_uri=http%3A%2F%2Flocalhost:3000/callback https://accounts.spotify.com/api/token
Enter fullscreen mode Exit fullscreen mode

因此,在对客户端 ID客户端密钥进行编码后,它应该看起来像这样——

YmRhMTBjZDcxOTU2NDg5ODgxODJmMmQ5NzcyN2RlN2U6NjZmZTU5OTJjYjZlNDFjZmEwNDdfkdjfkHKkjdfdwODk0YjI=
Enter fullscreen mode Exit fullscreen mode

最终的网址应该如下所示:

curl -H "Authorization: Basic YmRhMTBjZDcxOTU2NDg5ODgxODJmMmQ5NzcyN2RlN2U6NjZmZTU5OTJjYjZlNDFjZmEwNDdfkdjfkHKkjdfdwODk0YjI=" -d grant_type=authorization_code -d code=AQD_kIzZ0OVXkeeIU4jnLWADFJDKdcWLYo9ySdfdfdkHKJFtGExxgw_aCxJrZflWVeARvjaGDfdfddf6KYpFlo2t2JZ0SQceyvdKs4AcGgCLSqm7vMyiRWCy_t06WmLet8v6aEBx8U4eKHxKiEx_sBgvCSlYo5wptKUd0Gwa6oyqOHFZnE7KSbxTVwMkQ668Ezjz2aeFEPp1TU9ij6dM4AjO4YFCH2hoMWgO3k5XrbdKnK7U2Y30wb8gHjEA6LnE8yu8cyvaY9WQ -d redirect_uri=http%3A%2F%2Flocalhost:3000/callback https://accounts.spotify.com/api/token
Enter fullscreen mode Exit fullscreen mode

在终端运行此命令后,它将返回一个包含令牌的 JSON 对象refresh_token。除非您撤销访问权限,否则此令牌将一直有效,因此我们需要将其保存到环境变量中。JSON 对象如下所示:

{
  "access_token":"DKjdfkdjkdfjdRU67VlhTLc3HUHHRvcG6W3F56ISDFodvSiSmFZIIUwOzzZCyCcgOia-TXX-y_wq8n7jEHTI0JEYO6djABMQmlutMqsUPgEiVJ2isj98BrBYFV4dfdsjkfksudJKDUIkdfdfdk1vxR07V_r7Y-aLjMyqwBaSqxneFokM",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token":"dfkdjkkdjfdfrrdkfjd9984maWbrIrXqNNK63SOzJdWQGaTYQGD6Ji1dWsAywEgm-eUspfuOlug8f71XL2oBWtD_pzd6EzCWwqCVnDSWspbJelOwVDY62TuAI",
  "scope": "user-read-currently-playing user-top-read user-read-private"
}

Enter fullscreen mode Exit fullscreen mode

信息量有点大,但现在我们的工作完成了,我们已经获得了授权所需的一切。

设置环境变量

现在,我们需要将上述过程中得到的所有内容添加到…….env.local

SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
SPOTIFY_REFRESH_TOKEN=
Enter fullscreen mode Exit fullscreen mode

使用 Spotify API

现在我们可以使用它refresh_token来获取最终结果access_token。以下代码access_token使用以下方法获取结果:refresh_token

// lib/spotify.js

const getAccessToken = async () => {
  const refresh_token = process.env.SPOTIFY_REFRESH_TOKEN;

  const response = await fetch("https://accounts.spotify.com/api/token", {
    method: "POST",
    headers: {
      Authorization: `Basic ${Buffer.from(
        `${process.env.SPOTIFY_CLIENT_ID}:${process.env.SPOTIFY_CLIENT_SECRET}`
      ).toString("base64")}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token,
    }),
  });

  return response.json();
};
Enter fullscreen mode Exit fullscreen mode

获取热门歌曲

现在你可以用这个方法access_token来获取你的数据。在我们的例子中,它是获取热门歌曲的数据。

// lib/spotify.js

export const topTracks = async () => {
  const { access_token } = await getAccessToken();

  return fetch("https://api.spotify.com/v1/me/top/tracks", {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });
};
Enter fullscreen mode Exit fullscreen mode

创建 API 路线顶级轨道

开头我提到过我们会使用 Next.js API 路由。如果你还不熟悉,可以阅读一下这篇文章。

// pages/api/stats/tracks.js

import { topTracks } from "../../../lib/spotify";

export default async function handler(req, res) {
  const response = await topTracks();
  const { items } = await response.json();

  const tracks = items.slice(0, 5).map((track) => ({
    title: track.name,
    artist: track.artists.map((_artist) => _artist.name).join(", "),
    url: track.external_urls.spotify,
    coverImage: track.album.images[1],
  }));

  res.setHeader(
    "Cache-Control",
    "public, s-maxage=86400, stale-while-revalidate=43200"
  );

  return res.status(200).json(tracks);
}
Enter fullscreen mode Exit fullscreen mode

这将返回排名前五的歌曲,我已经删除了不必要的信息。您可以根据需要进行修改。现在访问该网站localhost:3000/api/stats/tracks。如果一切正常,您应该会看到类似这样的数据 -

// localhost:3000/api/stats/tracks

[
  // ...........
 {
    "title": "Blowing Up",
    "artist": "KR$NA",
    "url": "https://open.spotify.com/track/3Oh2FwWbnKIAyUE2gToFYu",
    "coverImage": {
      "height": 300,
      "url": "https://i.scdn.co/image/ab67616d00001e02f8c35169d5bab01327f87e5a",
      "width": 300
    }
  },
  {
    "title": "Jaan Bolti Hai",
    "artist": "Karma",
    "url": "https://open.spotify.com/track/4KGZlLtfKV4raRbsoB2Rw9",
    "coverImage": {
      "height": 300,
      "url": "https://i.scdn.co/image/ab67616d00001e028e3626063a42b11b847663b3",
      "width": 300
    }
  },
  //.........
]
Enter fullscreen mode Exit fullscreen mode

要查看我的统计数据,您可以访问https://jatin.vercel.app/api/stats/tracks

找到顶级艺术家

现在你可以用这个方法access_token来获取你的数据。在我们的例子中,它是排名前列的艺术家名单。

// lib/spotify.js

export const topArtists = async () => {
  const { access_token } = await getAccessToken();

  return fetch("https://api.spotify.com/v1/me/top/artists", {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });
};
Enter fullscreen mode Exit fullscreen mode

创建 API 路由顶级艺术家

// pages/api/stats/artists.js

import { topArtists } from "../../../lib/spotify";

export default async function handler(req, res) {
  const response = await topArtists();
  const { items } = await response.json();

  const artists = items.slice(0, 5).map((artist) => ({
    name: artist.name,
    url: artist.external_urls.spotify,
    coverImage: artist.images[1],
    followers: artist.followers.total,
  }));

  res.setHeader(
    "Cache-Control",
    "public, s-maxage=86400, stale-while-revalidate=43200"
  );

  return res.status(200).json(artists);
}
Enter fullscreen mode Exit fullscreen mode

它会返回你最喜欢的 Spotify 艺人。

获取当前播放的歌曲

现在,正如您在我网站页脚看到的,有一个选项可以查看我当前是否正在播放歌曲,如果是,则显示是哪首歌。为此,我们需要获取以下URL。

// lib/spotify.js

export const currentlyPlayingSong = async () => {
  const { access_token } = await getAccessToken();

  return fetch("https://api.spotify.com/v1/me/player/currently-playing", {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });
};
Enter fullscreen mode Exit fullscreen mode

为当前播放歌曲创建 API 路由

// pages/api/now-playing.js

import { currentlyPlayingSong } from "../../lib/spotify";

export default async function handler(req, res) {
  const response = await currentlyPlayingSong();

  if (response.status === 204 || response.status > 400) {
    return res.status(200).json({ isPlaying: false });
  }

  const song = await response.json();

  if (song.item === null) {
    return res.status(200).json({ isPlaying: false });
  }

  const isPlaying = song.is_playing;
  const title = song.item.name;
  const artist = song.item.artists.map((_artist) => _artist.name).join(", ");
  const album = song.item.album.name;
  const albumImageUrl = song.item.album.images[0].url;
  const songUrl = song.item.external_urls.spotify;

  res.setHeader(
    "Cache-Control",
    "public, s-maxage=60, stale-while-revalidate=30"
  );

  return res.status(200).json({
    album,
    albumImageUrl,
    artist,
    isPlaying,
    songUrl,
    title,
  });
}
Enter fullscreen mode Exit fullscreen mode

如果用户正在播放歌曲,则返回歌曲的所有详细信息。否则,isPlaying返回空值false。现在您可以处理这两种情况。如果用户正在播放歌曲,则直接显示歌曲信息;否则,显示“未播放”。

你应该使用它swr来获取数据,否则它会显示你可能不喜欢的旧数据。

输出

您可以在我的网站上查看示例。

总结

如果你喜欢这篇文章,别忘了点赞❤️。如有任何疑问或建议,欢迎留言。下次见!

你可以请我喝杯咖啡来表达你的支持。😊👇
给我买咖啡

文章来源:https://dev.to/j471n/how-to-use-spotify-api-with-nextjs-50o5