librespot-js/src/player.ts
2023-10-31 20:20:45 -05:00

82 lines
2.1 KiB
TypeScript

import Librespot from './index.js'
import { parseTrack, uriToBasics } from './utils/parse.js'
import { RawSpotifyPlaybackState } from './utils/rawtypes.js'
import { SpotifyObject, SpotifyTrack } from './utils/types.js'
interface SpotifyDevice {
id: string
isActive: boolean
isPrivateSession: boolean
isRestricted: boolean
name: string
type: string
volumePercent: number
}
interface SpotifyPlaybackState {
device: SpotifyDevice
shuffleState: boolean
repeatState: string
timestamp: number
context: SpotifyObject | null
progressMs: number
item: SpotifyTrack | null
currentlyPlayingType: string
actions: {
disallows: {
interrupting_playback?: boolean
pausing?: boolean
resuming?: boolean
seeking?: boolean
skipping_next?: boolean
skipping_prev?: boolean
toggling_repeat_context?: boolean
toggling_shuffle?: boolean
toggling_repeat_track?: boolean
transferring_playback?: boolean
}
}
isPlaying: boolean
}
export default class LibrespotPlayer {
#librespot: Librespot
constructor(librespot: Librespot) {
this.#librespot = librespot
}
async getState(): Promise<SpotifyPlaybackState> {
const response = await this.#librespot.fetchWithAuth(
`https://api.spotify.com/v1/me/player`
)
if (response.status == 204) throw new Error('Nothing is playing')
const data = <RawSpotifyPlaybackState>await response.json()
return {
device: {
id: data.device.id,
isActive: data.device.is_active,
isPrivateSession: data.device.is_private_session,
isRestricted: data.device.is_restricted,
name: data.device.name,
type: data.device.type,
volumePercent: data.device.volume_percent
},
shuffleState: data.shuffle_state,
repeatState: data.repeat_state,
timestamp: data.timestamp,
context: data.context
? {
...uriToBasics(data.context.uri),
externalUrl: data.context.external_urls.spotify
}
: null,
progressMs: data.progress_ms,
item: data.item ? parseTrack(data.item) : null,
currentlyPlayingType: data.currently_playing_type,
actions: data.actions,
isPlaying: data.is_playing
}
}
}