Skip to content

Instantly share code, notes, and snippets.

@lilpolymath
Created October 24, 2024 14:43
Show Gist options
  • Save lilpolymath/0d690f9fbdc58debd4cbb08e2a27f1c6 to your computer and use it in GitHub Desktop.
Save lilpolymath/0d690f9fbdc58debd4cbb08e2a27f1c6 to your computer and use it in GitHub Desktop.
Sample demo on how to use now-playing
// all wrapped inside <SpotifyContextProvider>
const Hero = () => {
const playingDetails = useSpotify();
const [playing, setPlaying] = useState(false);
const playerRef = useRef < HTMLAudioElement > null;
const statusText = playingDetails.isPlaying ? "NOW PLAYING" : "LAST PLAYED";
const handlePlayPause = () => {
if (!playingDetails.previewUrl) {
return;
}
if (playing) {
playerRef.current?.pause();
setPlaying(false);
} else {
playerRef.current?.play();
setPlaying(true);
}
};
useEffect(() => {
if (playingDetails.previewUrl && playerRef.current) {
setPlaying(false);
playerRef.current.src = playingDetails.previewUrl;
playerRef.current.load();
}
}, [JSON.stringify(playingDetails.previewUrl)]);
return (
<div>
{playingDetails.previewUrl && (
<audio
ref={playerRef}
src={playingDetails.previewUrl}
preload="auto"
onEnded={() => setPlaying(false)}
/>
)}
<button className="now-playing" onClick={() => handlePlayPause()}>
<span className="now-playing__status">{playing ? "yes" : "no"}</span>
</button>
<span className="sr-only">
{statusText}: {playingDetails.songName} BY {playingDetails.artistName}
</span>
</div>
);
};
// app/api/spotify/route.ts
import { NowPlaying, Providers } from "@bolajiolajide/now-playing";
export const dynamic = 'force-dynamic'
export const GET = async () => {
try {
if (process.env.NODE_ENV !== 'production') {
return new Response(JSON.stringify({
title: 'Test Song (Non-production env)',
artiste: 'Chronixx',
image_url: 'https://i.scdn.co/image/ab67616d0000b273fb3d081418a02919fb1bb58f',
is_playing: true,
preview_url: 'https://p.scdn.co/mp3-preview/2d7798a99d7c4091da509418b6b752463d569547?cid=98dee14da74049fdbc531633fec2f9ae',
url: ''
}), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
const nowPlaying = new NowPlaying(Providers.SPOTIFY, {
streamerArgs: {
clientId: process.env.SPOTIFY_CLIENT_ID!,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,
refreshToken: process.env.SPOTIFY_REFRESH_TOKEN!,
},
});
const playingDetails = await nowPlaying.fetchCurrentlyPlayingOrLastPlayed();
return new Response(JSON.stringify(playingDetails), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
};
"use client";
import { createContext, useState, useEffect, useContext } from "react";
export type SpotifyPlayingDetails = {
url: string;
artistName: string;
songName: string;
previewUrl: string;
coverImageUrl: string;
isPlaying: boolean;
loading: boolean;
};
const SpotifyContext = createContext({
url: "",
artistName: "",
songName: "",
previewUrl: "",
isPlaying: false,
coverImageUrl: "",
loading: false,
});
export const useSpotify = () =>
useContext<SpotifyPlayingDetails>(SpotifyContext);
export const SpotifyProvider = ({ children }) => {
const [playingDetails, setPlayingDetails] = useState<SpotifyPlayingDetails>({
url: "",
artistName: "",
songName: "",
previewUrl: "",
isPlaying: false,
coverImageUrl: "",
loading: true
});
useEffect(() => {
const fetchPlayingDetails = () => {
fetch("/api/spotify")
.then((res) => res.json())
.then((data) => {
setPlayingDetails({
url: data.url,
artistName: data.artiste,
songName: data.title,
previewUrl: data.preview_url,
coverImageUrl: data.image_url,
isPlaying: data.is_playing,
loading: false,
});
})
.catch((error) => {
setPlayingDetails((prev) => ({...prev, loading: false }));
console.error("Error fetching playing details:", error);
});
};
setPlayingDetails((prev) => ({...prev, loading: true }));
fetchPlayingDetails();
const intervalId = setInterval(fetchPlayingDetails, 30000);
return () => clearInterval(intervalId);
}, []);
return (
<SpotifyContext.Provider value={playingDetails}>
{children}
</SpotifyContext.Provider>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment