/** `GET /api/bandcamp/tracks`: a Bandcamp page resolved at play time. */ export interface TralbumTrack { /** Position in the parsed array — the stable handle used to re-resolve a * track after its signed URL expires. */ index: number; trackNum?: number; title: string; /** Seconds, fractional. */ duration?: number; streamUrl: string | null; /** False for preorder, unreleased and still-encoding tracks. They stay in * the list so numbering matches the release, but never enter the queue. */ streamable: boolean; /** Bandcamp caps free plays per track; a capped track may serve a clip. */ capped: boolean; } export interface Tralbum { sourceUrl: string; itemType: "album" | "track"; title?: string; artist?: string; artworkUrl?: string; tracks: TralbumTrack[]; /** Epoch ms of the fetch that produced these signed URLs. */ resolvedAt: number; } /** `GET /api/youtube/playlist`: a playlist's tracklist, for the player. */ export interface YouTubePlaylistTrack { videoId: string; title: string; /** Seconds. */ duration?: number; } export interface YouTubePlaylist { listId: string; title?: string; tracks: YouTubePlaylistTrack[]; }