@stargate91/pill-player 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/PillPlayer.tsx","../src/types/index.ts","../src/hooks/useAudioPlayer.ts","../src/utils/youtube.ts","../src/utils/time.ts","../src/engines/html5Engine.ts","../src/engines/mixcloudEngine.ts","../src/engines/soundCloudEngine.ts","../src/engines/youTubeEngine.ts","../src/components/Icons.tsx","../src/components/AudioTriggerPill.tsx","../src/components/SpectrumVisualizer.tsx","../src/components/AudioPlaylist.tsx","../src/components/AudioSeekbar.tsx","../src/components/PlayerHeader.tsx","../src/components/TrackInfo.tsx","../src/components/PlayerControls.tsx","../src/components/ProviderEmbeds.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback, type CSSProperties } from \"react\";\nimport type { PillPlayerProps, PillLabels, AudioTrack, EmbedMode } from \"../types\";\nimport { DEFAULT_PILL_LABELS } from \"../types\";\nimport { useAudioPlayer } from \"../hooks/useAudioPlayer\";\nimport { AudioTriggerPill } from \"./AudioTriggerPill\";\nimport { SpectrumVisualizer } from \"./SpectrumVisualizer\";\nimport { AudioPlaylist } from \"./AudioPlaylist\";\nimport { AudioSeekbar } from \"./AudioSeekbar\";\nimport { PlayerHeader } from \"./PlayerHeader\";\nimport { TrackInfo } from \"./TrackInfo\";\nimport { PlayerControls } from \"./PlayerControls\";\nimport { ProviderEmbeds } from \"./ProviderEmbeds\";\n\nexport function PillPlayer({\n tracks,\n theme = \"orbital\",\n colors,\n position = \"bottom-right\",\n icons,\n labels: customLabels,\n features = {},\n initialOpen = false,\n className = \"\",\n style,\n onTrackChange,\n onPlayStateChange,\n}: PillPlayerProps) {\n const [isOpen, setIsOpen] = useState(initialOpen);\n const [asyncTracks, setAsyncTracks] = useState<AudioTrack[]>([]);\n\n // If tracks is a string URL, load JSON asynchronously\n useEffect(() => {\n if (typeof tracks !== \"string\") return;\n let isMounted = true;\n fetch(tracks)\n .then((res) => {\n if (!res.ok) throw new Error(`Failed to fetch tracks: ${res.status}`);\n return res.json();\n })\n .then((data: AudioTrack[]) => {\n if (isMounted && Array.isArray(data)) {\n setAsyncTracks(data);\n }\n })\n .catch((err) => {\n console.error(\"[PillPlayer] Error loading tracks JSON:\", err);\n });\n\n return () => {\n isMounted = false;\n };\n }, [tracks]);\n\n const resolvedTracks: AudioTrack[] = typeof tracks === \"string\" ? asyncTracks : tracks;\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n const {\n showSpectrum = true,\n showPlaylist = true,\n showSeekbar = true,\n persistState = true,\n enableKeyboardShortcuts = true,\n embedMode: propEmbedMode,\n mixcloudEmbedMode: propMixcloudEmbedMode,\n beaconGlow = false,\n } = features;\n\n const embedMode: EmbedMode = propEmbedMode ?? propMixcloudEmbedMode ?? \"seamless\";\n\n const labels: PillLabels = {\n ...DEFAULT_PILL_LABELS,\n ...customLabels,\n };\n\n const {\n currentTrack,\n currentTrackIndex,\n isPlaying,\n isMuted,\n isLoaded,\n currentTime,\n duration,\n handleSeek,\n iframeRef,\n iframeSrc,\n scIframeRef,\n soundCloudIframeSrc,\n isSoundCloud,\n isYouTube,\n ytIframeRef,\n youTubeIframeSrc,\n setupYouTubePlayer,\n isHtmlAudio,\n setupSoundCloudWidget,\n frequencyData,\n hasLiveFrequency,\n timing,\n setIsLoaded,\n handleTogglePlay,\n handleToggleMute,\n handleNextTrack,\n handlePrevTrack,\n handleSelectTrack,\n setupMixcloudWidget,\n } = useAudioPlayer({\n tracks: resolvedTracks,\n persistState,\n onTrackChange,\n onPlayStateChange,\n });\n\n const handleToggleOpen = useCallback(() => {\n setIsOpen((prev) => {\n const next = !prev;\n if (next && !isLoaded) {\n setIsLoaded(true);\n }\n return next;\n });\n }, [isLoaded, setIsLoaded]);\n\n const handleClose = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n // Keyboard accessibility: Escape to close HUD\n useEffect(() => {\n if (!enableKeyboardShortcuts || !isOpen) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n handleClose();\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [enableKeyboardShortcuts, isOpen, handleClose]);\n\n // Click outside to collapse HUD\n useEffect(() => {\n if (!isOpen) return;\n\n const handlePointerDownOutside = (e: PointerEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n handleClose();\n }\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDownOutside);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDownOutside);\n }, [isOpen, handleClose]);\n\n // Custom colors CSS variables\n const customColorStyles = (colors\n ? {\n ...(colors.accent ? { \"--pp-accent\": colors.accent } : {}),\n ...(colors.secondary ? { \"--pp-accent-secondary\": colors.secondary } : {}),\n ...(colors.bg ? { \"--pp-bg\": colors.bg } : {}),\n ...(colors.surface ? { \"--pp-surface\": colors.surface } : {}),\n ...(colors.border ? { \"--pp-border\": colors.border } : {}),\n ...(colors.text ? { \"--pp-text\": colors.text } : {}),\n ...(colors.textDim ? { \"--pp-text-dim\": colors.textDim } : {}),\n ...(colors.glow ? { \"--pp-accent-glow\": colors.glow } : {}),\n }\n : {}) as CSSProperties;\n\n const externalLinkUrl =\n currentTrack?.externalUrl ||\n currentTrack?.soundcloud ||\n (currentTrack?.youtube\n ? currentTrack.youtube.startsWith(\"http\")\n ? currentTrack.youtube\n : \"https://www.youtube.com/watch?v=\" + currentTrack.youtube\n : undefined) ||\n (currentTrack?.feed ? \"https://www.mixcloud.com\" + currentTrack.feed : undefined);\n\n // Seekbar display rule:\n // Active when showSeekbar is true AND either:\n // 1. Current track is local audio (which never has an external widget)\n // 2. OR external widgets are hidden (embedMode === \"seamless\")\n const shouldShowSeekbar = showSeekbar && (isHtmlAudio || embedMode === \"seamless\");\n\n return (\n <div\n ref={containerRef}\n data-pill-theme={theme}\n className={\n \"pp-anchor \" +\n \"pp-position-\" + position + \" \" +\n (isPlaying ? \"pp-is-playing \" : \"\") +\n className\n }\n style={{\n ...customColorStyles,\n ...style,\n \"--bpm-beat\": timing.beatMs + \"ms\",\n \"--bpm-half-beat\": timing.halfBeatMs + \"ms\",\n \"--bpm-two-beats\": timing.twoBeatsMs + \"ms\",\n \"--bpm-bar\": timing.barMs + \"ms\",\n } as CSSProperties}\n aria-label={labels.badge}\n >\n {/* HUD Console Card */}\n <section\n role={isOpen ? \"dialog\" : undefined}\n aria-modal={isOpen ? \"false\" : undefined}\n aria-hidden={!isOpen}\n aria-label={currentTrack ? (currentTrack.code || \"\") + \" - \" + currentTrack.title : labels.badge}\n className={\"pp-hud-card \" + (isOpen ? \"pp-hud-card-open\" : \"pp-hud-card-closed\") + (beaconGlow && isOpen ? \" pp-hud-beacon\" : \"\")}\n >\n {/* Header */}\n <PlayerHeader\n labels={labels}\n icons={icons}\n onClose={handleClose}\n />\n\n {/* Body */}\n <div className=\"pp-card-body\">\n {/* Track Info */}\n <TrackInfo\n currentTrack={currentTrack}\n labels={labels}\n />\n\n {/* Equalizer Spectrum Visualizer */}\n {showSpectrum && (\n <SpectrumVisualizer\n isPlaying={isPlaying}\n labels={labels}\n frequencyData={frequencyData}\n hasLiveFrequency={hasLiveFrequency}\n />\n )}\n\n {/* Stream Providers (Mixcloud, SoundCloud, YouTube) */}\n <ProviderEmbeds\n isLoaded={isLoaded}\n embedMode={embedMode}\n currentTrack={currentTrack}\n labels={labels}\n isSoundCloud={isSoundCloud}\n soundCloudIframeSrc={soundCloudIframeSrc}\n scIframeRef={scIframeRef}\n onSoundCloudLoad={setupSoundCloudWidget}\n isYouTube={isYouTube}\n youTubeIframeSrc={youTubeIframeSrc}\n ytIframeRef={ytIframeRef}\n onYouTubeLoad={setupYouTubePlayer}\n iframeSrc={iframeSrc}\n iframeRef={iframeRef}\n onMixcloudLoad={setupMixcloudWidget}\n />\n\n {/* Audio Seekbar */}\n {shouldShowSeekbar && (\n <AudioSeekbar\n currentTime={currentTime}\n duration={duration}\n onSeek={handleSeek}\n />\n )}\n\n {/* Playback Controls */}\n <PlayerControls\n isPlaying={isPlaying}\n isMuted={isMuted}\n externalLinkUrl={externalLinkUrl}\n labels={labels}\n icons={icons}\n onPrev={handlePrevTrack}\n onTogglePlay={handleTogglePlay}\n onNext={handleNextTrack}\n onToggleMute={handleToggleMute}\n />\n\n {/* Playlist Tracklist Selection */}\n {showPlaylist && resolvedTracks.length > 1 && (\n <AudioPlaylist\n tracks={resolvedTracks}\n currentTrackIndex={currentTrackIndex}\n labels={labels}\n onSelectTrack={handleSelectTrack}\n />\n )}\n </div>\n </section>\n\n {/* Collapsed Floating Pill Toggle */}\n <AudioTriggerPill\n isOpen={isOpen}\n isPlaying={isPlaying}\n currentTrack={currentTrack}\n labels={labels}\n icons={icons}\n onToggleOpen={handleToggleOpen}\n />\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\n\nexport interface AudioTrack {\n id: string;\n title: string;\n code?: string;\n artist?: string;\n genre?: string;\n bpm?: number | string;\n duration?: string;\n src?: string; // Direct audio URL (MP3, AAC, stream)\n soundcloud?: string;// SoundCloud track URL\n youtube?: string; // YouTube video ID or URL\n feed?: string; // Mixcloud track feed path (e.g. /user/mix-title/)\n externalUrl?: string;\n}\n\nexport type PillTheme = \"orbital\" | \"stargate\" | \"cyberpunk\" | \"matrix\" | \"synthwave\" | \"amber\" | \"nordic\" | \"minimal\";\n\nexport type PillPosition = \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\" | \"inline\";\n\nexport interface PillColors {\n accent?: string;\n secondary?: string;\n bg?: string;\n surface?: string;\n border?: string;\n text?: string;\n textDim?: string;\n glow?: string;\n}\n\nexport type EmbedMode = \"seamless\" | \"themed\" | \"widget\";\nexport type MixcloudEmbedMode = EmbedMode;\n\nexport interface PillIcons {\n play?: ReactNode;\n pause?: ReactNode;\n prev?: ReactNode;\n next?: ReactNode;\n mute?: ReactNode;\n unmute?: ReactNode;\n close?: ReactNode;\n external?: ReactNode;\n}\n\nexport interface PillLabels {\n badge: string;\n openPlayer: string;\n closePlayer: string;\n play: string;\n pause: string;\n prevTrack: string;\n nextTrack: string;\n mute: string;\n unmute: string;\n directPlayHint: string;\n listenExternal: string;\n selectTrack: string;\n frequenciesActive: string;\n frequenciesStandby: string;\n spectrumHeader: string;\n spectrumDsp: string;\n subtitle: string;\n}\n\nexport interface PillFeatures {\n showSpectrum?: boolean;\n showSeekbar?: boolean;\n showPlaylist?: boolean;\n persistState?: boolean;\n enableKeyboardShortcuts?: boolean;\n embedMode?: EmbedMode; // \"seamless\" (headless HUD + native seekbar), \"themed\" (color-filtered widget), \"widget\" (raw iframe)\n mixcloudEmbedMode?: MixcloudEmbedMode; // Backwards-compatible alias for embedMode\n beaconGlow?: boolean; // Periodic breathing/dimming pulse (opacity 40% -> 100%)\n}\n\nexport interface PillPlayerProps {\n tracks: AudioTrack[] | string;\n theme?: PillTheme;\n colors?: PillColors;\n position?: PillPosition;\n icons?: PillIcons;\n labels?: Partial<PillLabels>;\n features?: PillFeatures;\n initialOpen?: boolean;\n className?: string;\n style?: React.CSSProperties;\n onTrackChange?: (track: AudioTrack, index: number) => void;\n onPlayStateChange?: (isPlaying: boolean) => void;\n}\n\nexport const DEFAULT_PILL_LABELS: PillLabels = {\n badge: \"AUDIO PLAYER\",\n openPlayer: \"Open player\",\n closePlayer: \"Close player\",\n play: \"Play\",\n pause: \"Pause\",\n prevTrack: \"Previous\",\n nextTrack: \"Next\",\n mute: \"Mute\",\n unmute: \"Unmute\",\n directPlayHint: \"Stream loaded. Use controls to play or pause.\",\n listenExternal: \"Open stream\",\n selectTrack: \"PLAYLIST\",\n frequenciesActive: \"PLAYING\",\n frequenciesStandby: \"PAUSED\",\n spectrumHeader: \"EQUALIZER\",\n spectrumDsp: \"\",\n subtitle: \"Audio\",\n};\n","import { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { AudioTrack } from \"../types\";\nimport { extractYouTubeId } from \"../utils/youtube\";\nimport { parseDurationToSeconds, calculateBpmTiming } from \"../utils/time\";\nimport type { EngineCallbacks } from \"../engines/types\";\nimport { useHtml5Engine } from \"../engines/html5Engine\";\nimport { useMixcloudEngine } from \"../engines/mixcloudEngine\";\nimport { useSoundCloudEngine } from \"../engines/soundCloudEngine\";\nimport { useYouTubeEngine } from \"../engines/youTubeEngine\";\n\nexport { extractYouTubeId } from \"../utils/youtube\";\n\nconst STORAGE_TRACK_KEY = \"pill_player_track_index\";\n\nexport interface UseAudioPlayerOptions {\n tracks: AudioTrack[];\n persistState?: boolean;\n onTrackChange?: (track: AudioTrack, index: number) => void;\n onPlayStateChange?: (isPlaying: boolean) => void;\n}\n\nexport function useAudioPlayer({\n tracks,\n persistState = true,\n onTrackChange,\n onPlayStateChange,\n}: UseAudioPlayerOptions) {\n const [currentTrackIndex, setCurrentTrackIndex] = useState(0);\n const [isPlaying, setIsPlaying] = useState(false);\n const [isMuted, setIsMuted] = useState(false);\n const [isLoaded, setIsLoaded] = useState(false);\n const [currentTime, setCurTime] = useState(0);\n const [duration, setDur] = useState(0);\n\n const currentTrack = tracks[currentTrackIndex] || tracks[0];\n\n const youTubeId = extractYouTubeId(\n currentTrack?.youtube || (currentTrack?.src && currentTrack.src.includes(\"youtube.com\") ? currentTrack.src : undefined)\n );\n const isYouTube = Boolean(youTubeId);\n\n const soundCloudUrl = currentTrack?.soundcloud || (currentTrack?.src && currentTrack.src.includes(\"soundcloud.com\") ? currentTrack.src : \"\");\n const isSoundCloud = Boolean(soundCloudUrl);\n\n const isMixcloud = Boolean(currentTrack?.feed);\n const isHtmlAudio = Boolean(currentTrack?.src && !currentTrack.src.includes(\"soundcloud.com\") && !currentTrack.src.includes(\"youtube.com\"));\n\n // Restore track index from persistence\n useEffect(() => {\n if (!persistState || typeof window === \"undefined\") return;\n try {\n const stored = localStorage.getItem(STORAGE_TRACK_KEY);\n if (stored !== null) {\n const parsed = parseInt(stored, 10);\n if (!isNaN(parsed) && parsed >= 0 && parsed < tracks.length) {\n setCurrentTrackIndex(parsed);\n }\n }\n } catch {}\n }, [persistState, tracks.length]);\n\n // Track next handler ref\n const nextTrackRef = useRef<() => void>(() => {});\n\n const callbacks: EngineCallbacks = useMemo(() => ({\n onPlay: () => {\n setIsPlaying(true);\n onPlayStateChange?.(true);\n },\n onPause: () => {\n setIsPlaying(false);\n onPlayStateChange?.(false);\n },\n onTimeUpdate: (time: number) => {\n setCurTime(time);\n },\n onDurationChange: (dur: number) => {\n setDur(dur);\n },\n onEnded: () => {\n nextTrackRef.current();\n },\n }), [onPlayStateChange]);\n\n // Engines\n const html5 = useHtml5Engine(callbacks);\n const mixcloud = useMixcloudEngine(isLoaded, isMixcloud, callbacks);\n const soundCloud = useSoundCloudEngine(isLoaded, isSoundCloud, callbacks);\n const youTube = useYouTubeEngine(isLoaded, isYouTube, isPlaying, isMuted, callbacks);\n\n // Track selection\n const handleSelectTrack = useCallback((index: number) => {\n if (index < 0 || index >= tracks.length) return;\n setCurrentTrackIndex(index);\n\n if (persistState && typeof window !== \"undefined\") {\n try {\n localStorage.setItem(STORAGE_TRACK_KEY, String(index));\n } catch {}\n }\n\n if (!isLoaded) {\n setIsLoaded(true);\n }\n\n const target = tracks[index];\n if (target) {\n setCurTime(0);\n setDur(parseDurationToSeconds(target.duration));\n onTrackChange?.(target, index);\n\n const targetYtId = extractYouTubeId(target.youtube);\n const targetScUrl = target.soundcloud || (target.src && target.src.includes(\"soundcloud.com\") ? target.src : \"\");\n const targetFeed = target.feed;\n const targetSrc = target.src && !target.src.includes(\"soundcloud.com\") && !target.src.includes(\"youtube.com\") ? target.src : \"\";\n\n // Pause inactive engines\n if (!targetSrc) html5.pause();\n if (!targetScUrl) soundCloud.pause();\n if (!targetFeed) mixcloud.pause();\n if (!targetYtId) youTube.pause();\n\n // Start active engine\n if (targetYtId) {\n youTube.loadTrack(targetYtId, true);\n } else if (targetScUrl) {\n soundCloud.loadTrack(targetScUrl, true);\n } else if (targetFeed) {\n mixcloud.loadTrack(targetFeed, true);\n } else if (targetSrc) {\n html5.loadTrack(targetSrc, true);\n }\n }\n }, [tracks, isLoaded, persistState, onTrackChange, html5, soundCloud, mixcloud, youTube]);\n\n const handleNextTrack = useCallback(() => {\n const nextIdx = currentTrackIndex < tracks.length - 1 ? currentTrackIndex + 1 : 0;\n handleSelectTrack(nextIdx);\n }, [currentTrackIndex, tracks.length, handleSelectTrack]);\n\n const handlePrevTrack = useCallback(() => {\n const prevIdx = currentTrackIndex > 0 ? currentTrackIndex - 1 : tracks.length - 1;\n handleSelectTrack(prevIdx);\n }, [currentTrackIndex, tracks.length, handleSelectTrack]);\n\n nextTrackRef.current = handleNextTrack;\n\n // Play / Pause toggle\n const handleTogglePlay = useCallback(() => {\n if (!isLoaded) {\n setIsLoaded(true);\n }\n\n if (isYouTube) {\n if (isPlaying) youTube.pause();\n else youTube.play();\n return;\n }\n\n if (isSoundCloud) {\n if (isPlaying) soundCloud.pause();\n else soundCloud.play();\n return;\n }\n\n if (isMixcloud) {\n if (isPlaying) mixcloud.pause();\n else mixcloud.play();\n return;\n }\n\n if (isHtmlAudio) {\n if (isPlaying) html5.pause();\n else html5.play();\n }\n }, [isLoaded, isYouTube, isSoundCloud, isMixcloud, isHtmlAudio, isPlaying, youTube, soundCloud, mixcloud, html5]);\n\n // Seek\n const handleSeek = useCallback((seconds: number) => {\n setCurTime(seconds);\n\n if (isYouTube) {\n youTube.seek(seconds);\n return;\n }\n if (isSoundCloud) {\n soundCloud.seek(seconds);\n return;\n }\n if (isMixcloud) {\n mixcloud.seek(seconds);\n return;\n }\n if (isHtmlAudio) {\n html5.seek(seconds);\n }\n }, [isYouTube, isSoundCloud, isMixcloud, isHtmlAudio, youTube, soundCloud, mixcloud, html5]);\n\n // Mute toggle\n const handleToggleMute = useCallback(() => {\n setIsMuted((prev) => {\n const nextMuted = !prev;\n html5.setMute(nextMuted);\n soundCloud.setMute(nextMuted);\n mixcloud.setMute(nextMuted);\n youTube.setMute(nextMuted);\n return nextMuted;\n });\n }, [html5, soundCloud, mixcloud, youTube]);\n\n // BPM Timing\n const timing = useMemo(() => calculateBpmTiming(currentTrack?.bpm), [currentTrack?.bpm]);\n\n // Iframe Sources\n const origin = typeof window !== \"undefined\" && window.location.origin ? encodeURIComponent(window.location.origin) : \"\";\n const youTubeIframeSrc = youTubeId\n ? \"https://www.youtube-nocookie.com/embed/\" +\n youTubeId +\n \"?enablejsapi=1&origin=\" +\n origin +\n \"&autoplay=0&controls=0&disablekb=1&fs=0&rel=0&playsinline=1\"\n : \"\";\n\n const soundCloudIframeSrc = soundCloudUrl\n ? \"https://w.soundcloud.com/player/?url=\" + encodeURIComponent(soundCloudUrl) + \"&auto_play=false&hide_related=true&show_comments=false&show_user=true&show_reposts=false&show_teaser=false&visual=false\"\n : \"\";\n\n const iframeSrc = currentTrack?.feed\n ? \"https://player-widget.mixcloud.com/widget/iframe/?feed=\" + encodeURIComponent(currentTrack.feed) + \"&hide_cover=1&light=0\"\n : \"\";\n\n return {\n tracks,\n currentTrack,\n currentTrackIndex,\n isPlaying,\n isMuted,\n isLoaded,\n currentTime,\n duration,\n handleSeek,\n iframeRef: mixcloud.iframeRef,\n scIframeRef: soundCloud.scIframeRef,\n soundCloudIframeSrc,\n isSoundCloud,\n isYouTube,\n ytIframeRef: youTube.ytIframeRef,\n youTubeIframeSrc,\n setupYouTubePlayer: youTube.setupYouTubePlayer,\n isHtmlAudio,\n isMixcloud,\n setupSoundCloudWidget: soundCloud.setupSoundCloudWidget,\n iframeSrc,\n frequencyData: html5.frequencyData,\n hasLiveFrequency: html5.hasLiveFrequency,\n timing,\n setIsLoaded,\n handleTogglePlay,\n handleToggleMute,\n handleNextTrack,\n handlePrevTrack,\n handleSelectTrack,\n setupMixcloudWidget: mixcloud.setupMixcloudWidget,\n };\n}\n","/**\n * Extracts 11-character YouTube video ID from various URL formats or returns the ID if already clean.\n */\nexport function extractYouTubeId(urlOrId?: string): string | null {\n if (!urlOrId) return null;\n const trimmed = urlOrId.trim();\n if (/^[a-zA-Z0-9_-]{11}$/.test(trimmed)) {\n return trimmed;\n }\n const match = trimmed.match(\n /(?:youtu\\.be\\/|youtube\\.com\\/(?:embed\\/|v\\/|watch\\?v=|watch\\?.+&v=|shorts\\/))([a-zA-Z0-9_-]{11})/\n );\n return match ? match[1] : null;\n}\n","/**\n * Formats seconds into mm:ss or hh:mm:ss string.\n */\nexport function formatTime(totalSeconds: number): string {\n if (isNaN(totalSeconds) || totalSeconds <= 0) return \"00:00\";\n const h = Math.floor(totalSeconds / 3600);\n const m = Math.floor((totalSeconds % 3600) / 60);\n const s = Math.floor(totalSeconds % 60);\n\n if (h > 0) {\n return (\n h.toString().padStart(2, \"0\") +\n \":\" +\n m.toString().padStart(2, \"0\") +\n \":\" +\n s.toString().padStart(2, \"0\")\n );\n }\n return m.toString().padStart(2, \"0\") + \":\" + s.toString().padStart(2, \"0\");\n}\n\n/**\n * Parses duration strings like \"3:45\", \"30 min\", or number of seconds.\n */\nexport function parseDurationToSeconds(duration?: string): number {\n if (!duration) return 0;\n const parts = duration.split(\":\");\n if (parts.length === 2) {\n const min = parseInt(parts[0], 10);\n const sec = parseInt(parts[1], 10);\n if (!isNaN(min) && !isNaN(sec)) return min * 60 + sec;\n }\n if (duration.includes(\"min\")) {\n const parsed = parseInt(duration, 10);\n if (!isNaN(parsed)) return parsed * 60;\n }\n const directNum = parseFloat(duration);\n return !isNaN(directNum) ? directNum : 0;\n}\n\n/**\n * Calculates beat, half-beat, two-beats, and bar timings in milliseconds from BPM.\n */\nexport function calculateBpmTiming(bpm?: number | string): {\n numericBpm: number;\n beatMs: number;\n halfBeatMs: number;\n twoBeatsMs: number;\n barMs: number;\n} {\n const numericBpm = typeof bpm === \"number\"\n ? bpm\n : parseInt(String(bpm || \"174\").replace(/[^0-9]/g, \"\"), 10) || 174;\n\n const beatMs = Math.round((60 / numericBpm) * 1000);\n const halfBeatMs = Math.round(beatMs / 2);\n const twoBeatsMs = Math.round(beatMs * 2);\n const barMs = Math.round(beatMs * 4);\n\n return { numericBpm, beatMs, halfBeatMs, twoBeatsMs, barMs };\n}\n","import { useState, useRef, useEffect, useCallback } from \"react\";\nimport type { EngineCallbacks } from \"./types\";\n\nexport function useHtml5Engine(callbacks: EngineCallbacks) {\n const [frequencyData, setFrequencyData] = useState<number[]>(new Array(16).fill(0));\n\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const animFrameRef = useRef<number | null>(null);\n\n // Initialize audio element & analyser loop\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const audio = new Audio();\n audio.preload = \"metadata\";\n audioRef.current = audio;\n\n audio.ontimeupdate = () => {\n callbacks.onTimeUpdate(audio.currentTime);\n };\n\n audio.onloadedmetadata = () => {\n callbacks.onDurationChange(audio.duration || 0);\n };\n\n audio.ondurationchange = () => {\n callbacks.onDurationChange(audio.duration || 0);\n };\n\n audio.onplay = () => {\n callbacks.onPlay();\n if (audioContextRef.current?.state === \"suspended\") {\n audioContextRef.current.resume().catch(() => {});\n }\n };\n\n audio.onpause = () => {\n callbacks.onPause();\n setFrequencyData(new Array(16).fill(0));\n };\n\n audio.onended = () => {\n callbacks.onEnded();\n };\n\n // Frequency analyzer render loop\n const updateFrequencies = () => {\n if (analyserRef.current) {\n const bufferLength = analyserRef.current.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n analyserRef.current.getByteFrequencyData(dataArray);\n\n const bands = 16;\n const step = Math.max(1, Math.floor(bufferLength / bands));\n const normalized = new Array(bands).fill(0).map((_, i) => {\n const val = dataArray[i * step] || 0;\n return val / 255;\n });\n setFrequencyData(normalized);\n }\n animFrameRef.current = requestAnimationFrame(updateFrequencies);\n };\n\n animFrameRef.current = requestAnimationFrame(updateFrequencies);\n\n return () => {\n if (animFrameRef.current) {\n cancelAnimationFrame(animFrameRef.current);\n }\n audio.pause();\n audio.src = \"\";\n if (audioContextRef.current && audioContextRef.current.state !== \"closed\") {\n audioContextRef.current.close().catch(() => {});\n }\n };\n }, [callbacks]);\n\n const initAudioContext = useCallback(() => {\n if (!audioContextRef.current && audioRef.current && typeof window !== \"undefined\") {\n try {\n const AudioCtx = window.AudioContext || window.webkitAudioContext;\n if (AudioCtx) {\n const ctx = new AudioCtx();\n const source = ctx.createMediaElementSource(audioRef.current);\n const analyser = ctx.createAnalyser();\n analyser.fftSize = 64;\n source.connect(analyser);\n analyser.connect(ctx.destination);\n audioContextRef.current = ctx;\n analyserRef.current = analyser;\n }\n } catch {}\n }\n }, []);\n\n const loadTrack = useCallback((src: string, autoPlay = true) => {\n if (!audioRef.current) return;\n audioRef.current.src = src;\n if (autoPlay) {\n initAudioContext();\n audioRef.current.play().catch(() => {});\n }\n }, [initAudioContext]);\n\n const play = useCallback(() => {\n initAudioContext();\n audioRef.current?.play().catch(() => {});\n }, [initAudioContext]);\n\n const pause = useCallback(() => {\n audioRef.current?.pause();\n setFrequencyData(new Array(16).fill(0));\n }, []);\n\n const seek = useCallback((seconds: number) => {\n if (audioRef.current) {\n audioRef.current.currentTime = seconds;\n }\n }, []);\n\n const setMute = useCallback((muted: boolean) => {\n if (audioRef.current) {\n audioRef.current.muted = muted;\n }\n }, []);\n\n return {\n audioRef,\n frequencyData,\n hasLiveFrequency: frequencyData.some((v) => v > 0.05),\n loadTrack,\n play,\n pause,\n seek,\n setMute,\n initAudioContext,\n };\n}\n","import { useRef, useEffect, useCallback } from \"react\";\nimport type { EngineCallbacks, MixcloudWidgetInstance } from \"./types\";\n\nconst ALLOWED_ORIGINS = new Set([\n \"https://player-widget.mixcloud.com\",\n \"https://www.mixcloud.com\",\n \"https://widget.mixcloud.com\",\n]);\n\nexport function useMixcloudEngine(\n isLoaded: boolean,\n isMixcloud: boolean,\n callbacks: EngineCallbacks\n) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const widgetRef = useRef<MixcloudWidgetInstance | null>(null);\n const isWidgetReadyRef = useRef(false);\n const pendingPlayRef = useRef(false);\n\n const setupMixcloudWidget = useCallback(() => {\n if (!iframeRef.current || typeof window === \"undefined\" || !window.Mixcloud) return;\n\n try {\n const widget = window.Mixcloud.PlayerWidget(iframeRef.current);\n widgetRef.current = widget;\n\n widget.ready\n .then((resolved) => {\n const active = resolved || widget;\n widgetRef.current = active;\n isWidgetReadyRef.current = true;\n\n active.events?.play?.on?.(() => {\n callbacks.onPlay();\n active.getDuration?.().then((dur) => {\n if (typeof dur === \"number\" && dur > 0) callbacks.onDurationChange(dur);\n }).catch(() => {});\n });\n\n active.events?.pause?.on?.(() => callbacks.onPause());\n\n active.events?.progress?.on?.((pos: number, dur: number) => {\n callbacks.onPlay();\n if (typeof pos === \"number\") callbacks.onTimeUpdate(pos);\n if (typeof dur === \"number\" && dur > 0) callbacks.onDurationChange(dur);\n });\n\n active.events?.ended?.on?.(() => callbacks.onEnded());\n\n if (pendingPlayRef.current) {\n pendingPlayRef.current = false;\n active.play?.().catch(() => {});\n }\n })\n .catch(() => {});\n } catch {}\n }, [callbacks]);\n\n // Lazy load Mixcloud script\n useEffect(() => {\n if (typeof window === \"undefined\" || !isLoaded || !isMixcloud) return;\n\n if (window.Mixcloud) {\n setupMixcloudWidget();\n return;\n }\n\n let script = document.getElementById(\"mixcloud-widget-api\") as HTMLScriptElement | null;\n if (!script) {\n script = document.createElement(\"script\");\n script.id = \"mixcloud-widget-api\";\n script.src = \"https://widget.mixcloud.com/media/js/widgetApi.js\";\n script.async = true;\n document.body.appendChild(script);\n }\n\n const onLoad = () => setupMixcloudWidget();\n script.addEventListener(\"load\", onLoad);\n return () => script?.removeEventListener(\"load\", onLoad);\n }, [isLoaded, isMixcloud, setupMixcloudWidget]);\n\n // PostMessage sync\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const handleMessage = (event: MessageEvent) => {\n if (!ALLOWED_ORIGINS.has(event.origin)) return;\n try {\n let data = event.data;\n if (typeof data === \"string\" && (data.includes(\"play\") || data.includes(\"pause\") || data.includes(\"ended\"))) {\n data = JSON.parse(data);\n }\n if (typeof data === \"object\" && data !== null) {\n const eventName = data.widgetEvent || data.event || data.type;\n if (eventName === \"play\") callbacks.onPlay();\n else if (eventName === \"pause\") callbacks.onPause();\n else if (eventName === \"ended\") callbacks.onEnded();\n }\n } catch {}\n };\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [callbacks]);\n\n // Polling sync\n useEffect(() => {\n if (!isLoaded || !isMixcloud) return;\n\n const interval = setInterval(() => {\n const widget = widgetRef.current;\n if (widget && typeof widget.getIsPaused === \"function\") {\n widget\n .getIsPaused()\n .then((isPaused) => {\n if (isPaused) callbacks.onPause();\n else callbacks.onPlay();\n })\n .catch(() => {});\n\n if (typeof widget.getPosition === \"function\") {\n widget.getPosition().then((pos) => {\n if (typeof pos === \"number\") callbacks.onTimeUpdate(pos);\n }).catch(() => {});\n }\n }\n }, 800);\n\n return () => clearInterval(interval);\n }, [isLoaded, isMixcloud, callbacks]);\n\n const loadTrack = useCallback((feed: string, autoPlay = true) => {\n const widget = widgetRef.current;\n if (widget?.load) {\n widget.load(feed, autoPlay).catch(() => {});\n if (autoPlay) callbacks.onPlay();\n } else {\n pendingPlayRef.current = autoPlay;\n if (autoPlay) callbacks.onPlay();\n }\n }, [callbacks]);\n\n const play = useCallback(() => {\n const widget = widgetRef.current;\n if (widget?.play) {\n widget.play().catch(() => {});\n callbacks.onPlay();\n } else {\n pendingPlayRef.current = true;\n callbacks.onPlay();\n }\n }, [callbacks]);\n\n const pause = useCallback(() => {\n const widget = widgetRef.current;\n if (widget?.pause) {\n widget.pause().catch(() => {});\n callbacks.onPause();\n }\n }, [callbacks]);\n\n const seek = useCallback((seconds: number) => {\n const widget = widgetRef.current;\n if (widget && typeof widget.seek === \"function\") {\n widget.seek(seconds).catch(() => {});\n }\n }, []);\n\n const setMute = useCallback((muted: boolean) => {\n const widget = widgetRef.current;\n if (widget?.setVolume) {\n widget.setVolume(muted ? 0 : 1).catch(() => {});\n }\n }, []);\n\n return {\n iframeRef,\n widgetRef,\n setupMixcloudWidget,\n loadTrack,\n play,\n pause,\n seek,\n setMute,\n };\n}\n","import { useRef, useEffect, useCallback } from \"react\";\nimport type { EngineCallbacks, SoundCloudWidgetInstance } from \"./types\";\n\nexport function useSoundCloudEngine(\n isLoaded: boolean,\n isSoundCloud: boolean,\n callbacks: EngineCallbacks\n) {\n const scIframeRef = useRef<HTMLIFrameElement | null>(null);\n const scWidgetRef = useRef<SoundCloudWidgetInstance | null>(null);\n const pendingPlayRef = useRef(false);\n\n const setupSoundCloudWidget = useCallback(() => {\n if (!scIframeRef.current || typeof window === \"undefined\" || !window.SC?.Widget) return;\n\n try {\n const widget = window.SC.Widget(scIframeRef.current);\n scWidgetRef.current = widget;\n\n const events = window.SC?.Widget?.Events;\n if (!events) return;\n\n widget.bind(events.READY, () => {\n widget.getDuration?.((ms: number) => {\n if (ms) callbacks.onDurationChange(ms / 1000);\n });\n\n widget.bind(events.PLAY, () => {\n callbacks.onPlay();\n widget.getDuration?.((ms: number) => {\n if (ms) callbacks.onDurationChange(ms / 1000);\n });\n });\n\n widget.bind(events.PAUSE, () => callbacks.onPause());\n widget.bind(events.FINISH, () => callbacks.onEnded());\n\n widget.bind(events.PLAY_PROGRESS, (data: any) => {\n if (data && typeof data.currentPosition === \"number\") {\n callbacks.onTimeUpdate(data.currentPosition / 1000);\n }\n if (data && typeof data.relativePosition === \"number\" && data.relativePosition > 0 && typeof data.currentPosition === \"number\") {\n const calculatedDuration = (data.currentPosition / data.relativePosition) / 1000;\n if (!isNaN(calculatedDuration) && isFinite(calculatedDuration) && calculatedDuration > 0) {\n callbacks.onDurationChange(calculatedDuration);\n }\n }\n });\n\n if (pendingPlayRef.current) {\n pendingPlayRef.current = false;\n widget.play();\n }\n });\n } catch {}\n }, [callbacks]);\n\n // Lazy load SoundCloud script\n useEffect(() => {\n if (typeof window === \"undefined\" || !isLoaded || !isSoundCloud) return;\n\n if (window.SC?.Widget) {\n setupSoundCloudWidget();\n return;\n }\n\n let script = document.getElementById(\"soundcloud-widget-api\") as HTMLScriptElement | null;\n if (!script) {\n script = document.createElement(\"script\");\n script.id = \"soundcloud-widget-api\";\n script.src = \"https://w.soundcloud.com/player/api.js\";\n script.async = true;\n document.body.appendChild(script);\n }\n\n const onLoad = () => setupSoundCloudWidget();\n script.addEventListener(\"load\", onLoad);\n return () => script?.removeEventListener(\"load\", onLoad);\n }, [isLoaded, isSoundCloud, setupSoundCloudWidget]);\n\n const loadTrack = useCallback((url: string, autoPlay = true) => {\n const widget = scWidgetRef.current;\n if (widget?.load) {\n widget.load(url, { auto_play: autoPlay });\n if (autoPlay) callbacks.onPlay();\n } else {\n pendingPlayRef.current = autoPlay;\n if (autoPlay) callbacks.onPlay();\n }\n }, [callbacks]);\n\n const play = useCallback(() => {\n const widget = scWidgetRef.current;\n if (widget?.play) {\n widget.play();\n callbacks.onPlay();\n } else {\n pendingPlayRef.current = true;\n callbacks.onPlay();\n }\n }, [callbacks]);\n\n const pause = useCallback(() => {\n const widget = scWidgetRef.current;\n if (widget?.pause) {\n widget.pause();\n callbacks.onPause();\n }\n }, [callbacks]);\n\n const seek = useCallback((seconds: number) => {\n const widget = scWidgetRef.current;\n if (widget?.seekTo) {\n widget.seekTo(seconds * 1000);\n }\n }, []);\n\n const setMute = useCallback((muted: boolean) => {\n const widget = scWidgetRef.current;\n if (widget?.setVolume) {\n widget.setVolume(muted ? 0 : 100);\n }\n }, []);\n\n return {\n scIframeRef,\n scWidgetRef,\n setupSoundCloudWidget,\n loadTrack,\n play,\n pause,\n seek,\n setMute,\n };\n}\n","import { useRef, useEffect, useCallback } from \"react\";\nimport type { EngineCallbacks } from \"./types\";\n\nexport function useYouTubeEngine(\n isLoaded: boolean,\n isYouTube: boolean,\n isPlaying: boolean,\n isMuted: boolean,\n callbacks: EngineCallbacks\n) {\n const ytIframeRef = useRef<HTMLIFrameElement | null>(null);\n const ytPlayerRef = useRef<any>(null);\n const pendingPlayRef = useRef(false);\n\n const setupYouTubePlayer = useCallback(() => {\n if (!ytIframeRef.current || typeof window === \"undefined\" || !window.YT?.Player) return;\n\n try {\n if (ytPlayerRef.current) return;\n\n new window.YT.Player(ytIframeRef.current, {\n events: {\n onReady: (event: any) => {\n ytPlayerRef.current = event.target;\n const dur = event.target.getDuration?.();\n if (dur && typeof dur === \"number\" && dur > 0) {\n callbacks.onDurationChange(dur);\n }\n if (isMuted) {\n event.target.mute?.();\n }\n if (pendingPlayRef.current) {\n pendingPlayRef.current = false;\n event.target.playVideo?.();\n }\n },\n onStateChange: (event: any) => {\n // 1 = PLAYING, 2 = PAUSED, 0 = ENDED\n if (event.data === 1) {\n callbacks.onPlay();\n const dur = event.target.getDuration?.();\n if (dur && typeof dur === \"number\" && dur > 0) {\n callbacks.onDurationChange(dur);\n }\n } else if (event.data === 2) {\n callbacks.onPause();\n } else if (event.data === 0) {\n callbacks.onEnded();\n }\n },\n },\n });\n } catch {}\n }, [callbacks, isMuted]);\n\n // Lazy load YouTube script\n useEffect(() => {\n if (typeof window === \"undefined\" || !isLoaded || !isYouTube) return;\n\n if (window.YT && window.YT.Player) {\n setupYouTubePlayer();\n return;\n }\n\n let script = document.getElementById(\"youtube-iframe-api\") as HTMLScriptElement | null;\n if (!script) {\n script = document.createElement(\"script\");\n script.id = \"youtube-iframe-api\";\n script.src = \"https://www.youtube.com/iframe_api\";\n script.async = true;\n document.body.appendChild(script);\n }\n\n const prevOnReady = (window as any).onYouTubeIframeAPIReady;\n (window as any).onYouTubeIframeAPIReady = () => {\n prevOnReady?.();\n setupYouTubePlayer();\n };\n }, [isLoaded, isYouTube, setupYouTubePlayer]);\n\n // Time & duration polling\n useEffect(() => {\n if (!isYouTube || !isPlaying || !ytPlayerRef.current) return;\n\n const interval = setInterval(() => {\n const player = ytPlayerRef.current;\n if (player && typeof player.getCurrentTime === \"function\") {\n try {\n const time = player.getCurrentTime();\n if (typeof time === \"number\") callbacks.onTimeUpdate(time);\n const dur = player.getDuration?.();\n if (typeof dur === \"number\" && dur > 0) callbacks.onDurationChange(dur);\n } catch {}\n }\n }, 400);\n\n return () => clearInterval(interval);\n }, [isYouTube, isPlaying, callbacks]);\n\n const loadTrack = useCallback((ytId: string, autoPlay = true) => {\n const player = ytPlayerRef.current;\n if (player && typeof player.loadVideoById === \"function\") {\n player.loadVideoById(ytId);\n if (autoPlay) callbacks.onPlay();\n } else {\n pendingPlayRef.current = autoPlay;\n if (autoPlay) callbacks.onPlay();\n }\n }, [callbacks]);\n\n const play = useCallback(() => {\n const player = ytPlayerRef.current;\n if (player?.playVideo) {\n player.playVideo();\n callbacks.onPlay();\n } else {\n pendingPlayRef.current = true;\n callbacks.onPlay();\n }\n }, [callbacks]);\n\n const pause = useCallback(() => {\n const player = ytPlayerRef.current;\n if (player?.pauseVideo) {\n player.pauseVideo();\n callbacks.onPause();\n }\n }, [callbacks]);\n\n const seek = useCallback((seconds: number) => {\n ytPlayerRef.current?.seekTo?.(seconds, true);\n }, []);\n\n const setMute = useCallback((muted: boolean) => {\n if (ytPlayerRef.current) {\n if (muted) ytPlayerRef.current.mute?.();\n else ytPlayerRef.current.unMute?.();\n }\n }, []);\n\n return {\n ytIframeRef,\n ytPlayerRef,\n setupYouTubePlayer,\n loadTrack,\n play,\n pause,\n seek,\n setMute,\n };\n}\n","import type { SVGProps } from \"react\";\n\nexport interface IconProps extends SVGProps<SVGSVGElement> {\n size?: number | string;\n}\n\nexport function PlayIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n aria-hidden=\"true\"\n {...props}\n >\n <polygon points=\"6 4 20 12 6 20 6 4\" />\n </svg>\n );\n}\n\nexport function PauseIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n aria-hidden=\"true\"\n {...props}\n >\n <rect x=\"5\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"15\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n );\n}\n\nexport function SkipBackIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n aria-hidden=\"true\"\n {...props}\n >\n <polygon points=\"19 20 9 12 19 4 19 20\" />\n <line x1=\"5\" y1=\"4\" x2=\"5\" y2=\"20\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nexport function SkipForwardIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n stroke=\"none\"\n aria-hidden=\"true\"\n {...props}\n >\n <polygon points=\"5 4 15 12 5 20 5 4\" />\n <line x1=\"19\" y1=\"4\" x2=\"19\" y2=\"20\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\nexport function VolumeMuteIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" fill=\"currentColor\" stroke=\"none\" />\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\" />\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\" />\n </svg>\n );\n}\n\nexport function VolumeUpIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\" />\n </svg>\n );\n}\n\nexport function CloseIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n\nexport function ExternalLinkIcon({ size = 16, ...props }: IconProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n","import type { AudioTrack, PillLabels, PillIcons } from \"../types\";\nimport { PlayIcon, PauseIcon } from \"./Icons\";\n\nexport interface AudioTriggerPillProps {\n isOpen: boolean;\n isPlaying: boolean;\n currentTrack?: AudioTrack;\n labels: PillLabels;\n icons?: PillIcons;\n onToggleOpen: () => void;\n}\n\nexport function AudioTriggerPill({\n isOpen,\n isPlaying,\n currentTrack,\n labels,\n icons,\n onToggleOpen,\n}: AudioTriggerPillProps) {\n return (\n <button\n type=\"button\"\n className=\"pp-pill-btn\"\n onClick={onToggleOpen}\n aria-expanded={isOpen}\n aria-label={isOpen ? labels.closePlayer : labels.openPlayer}\n >\n <span className=\"pp-pill-equalizer\" aria-hidden=\"true\">\n <span className=\"pp-pill-bar\" />\n <span className=\"pp-pill-bar\" />\n <span className=\"pp-pill-bar\" />\n <span className=\"pp-pill-bar\" />\n </span>\n\n <span className=\"pp-pill-meta\">\n <span className=\"pp-pill-code\">{currentTrack?.code || currentTrack?.title || \"AUDIO\"}</span>\n {currentTrack?.bpm && (\n <span className=\"pp-pill-bpm\">• {currentTrack.bpm}</span>\n )}\n </span>\n\n <span className=\"pp-pill-icon\" aria-hidden=\"true\">\n {isPlaying\n ? (icons?.pause ?? <PauseIcon size={12} />)\n : (icons?.play ?? <PlayIcon size={12} />)}\n </span>\n </button>\n );\n}\n","import type { CSSProperties } from \"react\";\nimport type { PillLabels } from \"../types\";\n\nexport interface SpectrumVisualizerProps {\n isPlaying: boolean;\n labels: PillLabels;\n frequencyData?: number[];\n hasLiveFrequency?: boolean;\n}\n\nexport function SpectrumVisualizer({\n isPlaying,\n labels,\n frequencyData = [],\n hasLiveFrequency = false,\n}: SpectrumVisualizerProps) {\n return (\n <div className=\"pp-visualizer\" aria-hidden=\"true\">\n <div className=\"pp-vis-header\">\n <span className=\"pp-vis-title\">\n {labels.spectrumHeader}\n {labels.spectrumDsp ? (\n <span className=\"pp-vis-dsp\"> // {labels.spectrumDsp}</span>\n ) : null}\n </span>\n <span className=\"pp-vis-status\">\n <span className={\"pp-status-led \" + (isPlaying ? \"pp-status-led-active\" : \"\")} />\n <span>{isPlaying ? labels.frequenciesActive : labels.frequenciesStandby}</span>\n </span>\n </div>\n\n <div className=\"pp-vis-stage\">\n <div className=\"pp-vis-grid\">\n <span className=\"pp-grid-line\" />\n <span className=\"pp-grid-line\" />\n <span className=\"pp-grid-line\" />\n </div>\n\n <div className=\"pp-vis-bars\">\n {Array.from({ length: 16 }, (_, i) => {\n // When NOT playing: explicitly empty (flat 3px baseline, dim opacity, no animation)\n let barStyle: CSSProperties | undefined;\n\n if (!isPlaying) {\n barStyle = {\n height: \"3px\",\n opacity: 0.25,\n animation: \"none\",\n };\n } else if (hasLiveFrequency) {\n // Live Web Audio analyser levels\n const liveVal = frequencyData[i] || 0;\n barStyle = {\n height: Math.max(3, Math.round(liveVal * 38)) + \"px\",\n opacity: Math.max(0.45, liveVal),\n animation: \"none\",\n };\n } else {\n // Fallback to CSS BPM animations when playing without Web Audio API (e.g. Mixcloud)\n barStyle = undefined;\n }\n\n return (\n <div key={\"bar-\" + i} className=\"pp-bar-col\">\n <span className=\"pp-spectrum-bar\" style={barStyle} />\n </div>\n );\n })}\n </div>\n </div>\n\n <div className=\"pp-freq-scale\">\n <span>32Hz</span>\n <span>125Hz</span>\n <span>500Hz</span>\n <span>2kHz</span>\n <span>8kHz</span>\n <span>16kHz</span>\n </div>\n </div>\n );\n}\n","import type { AudioTrack, PillLabels } from \"../types\";\n\nexport interface AudioPlaylistProps {\n tracks: AudioTrack[];\n currentTrackIndex: number;\n labels: PillLabels;\n onSelectTrack: (index: number) => void;\n}\n\nexport function AudioPlaylist({\n tracks,\n currentTrackIndex,\n labels,\n onSelectTrack,\n}: AudioPlaylistProps) {\n return (\n <div className=\"pp-playlist\">\n <div className=\"pp-playlist-header\">\n <span>{labels.selectTrack}</span>\n <span>{currentTrackIndex + 1} / {tracks.length}</span>\n </div>\n\n <div className=\"pp-playlist-list\" role=\"listbox\" aria-label={labels.selectTrack}>\n {tracks.map((track, idx) => {\n const isSelected = idx === currentTrackIndex;\n\n return (\n <button\n key={track.id || \"track-\" + idx}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n className={\"pp-track-item \" + (isSelected ? \"pp-track-item-active\" : \"\")}\n onClick={() => onSelectTrack(idx)}\n >\n <div className=\"pp-track-item-left\">\n <span className=\"pp-track-item-code\">{track.code || \"#\" + (idx + 1)}</span>\n <span className=\"pp-track-item-title\">{track.title}</span>\n </div>\n <div className=\"pp-track-item-right\">\n {track.bpm && <span>{track.bpm}</span>}\n {track.duration && <span>{track.duration}</span>}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","import { useState, useRef, useCallback, useEffect, type MouseEvent, type TouchEvent, type KeyboardEvent } from \"react\";\nimport { formatTime } from \"../utils/time\";\n\nexport interface AudioSeekbarProps {\n currentTime: number;\n duration: number;\n onSeek: (timeInSeconds: number) => void;\n}\n\n\n\nexport function AudioSeekbar({\n currentTime,\n duration,\n onSeek,\n}: AudioSeekbarProps) {\n const [isDragging, setIsDragging] = useState(false);\n const [dragProgress, setDragProgress] = useState(0);\n const trackRef = useRef<HTMLDivElement>(null);\n\n const progress = duration > 0\n ? Math.min(1, Math.max(0, isDragging ? dragProgress : currentTime / duration))\n : 0;\n\n const calculateRatio = useCallback((clientX: number) => {\n if (!trackRef.current) return 0;\n const rect = trackRef.current.getBoundingClientRect();\n const pos = clientX - rect.left;\n return Math.min(1, Math.max(0, pos / rect.width));\n }, []);\n\n const handlePointerDown = (e: MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n setIsDragging(true);\n const ratio = calculateRatio(e.clientX);\n setDragProgress(ratio);\n };\n\n const handleTouchStart = (e: TouchEvent<HTMLDivElement>) => {\n if (e.touches[0]) {\n setIsDragging(true);\n const ratio = calculateRatio(e.touches[0].clientX);\n setDragProgress(ratio);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (duration <= 0) return;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") {\n e.preventDefault();\n onSeek(Math.min(duration, currentTime + 5));\n } else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") {\n e.preventDefault();\n onSeek(Math.max(0, currentTime - 5));\n } else if (e.key === \"PageUp\") {\n e.preventDefault();\n onSeek(Math.min(duration, currentTime + 30));\n } else if (e.key === \"PageDown\") {\n e.preventDefault();\n onSeek(Math.max(0, currentTime - 30));\n }\n };\n\n useEffect(() => {\n if (!isDragging) return;\n\n const handleMouseMove = (e: globalThis.MouseEvent) => {\n const ratio = calculateRatio(e.clientX);\n setDragProgress(ratio);\n };\n\n const handleTouchMove = (e: globalThis.TouchEvent) => {\n if (e.touches[0]) {\n const ratio = calculateRatio(e.touches[0].clientX);\n setDragProgress(ratio);\n }\n };\n\n const handleRelease = (e: globalThis.MouseEvent | globalThis.TouchEvent) => {\n let clientX = 0;\n if (\"clientX\" in e) {\n clientX = e.clientX;\n } else if (e.changedTouches && e.changedTouches[0]) {\n clientX = e.changedTouches[0].clientX;\n }\n const ratio = calculateRatio(clientX);\n setIsDragging(false);\n if (duration > 0) {\n onSeek(ratio * duration);\n }\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleRelease);\n window.addEventListener(\"touchmove\", handleTouchMove);\n window.addEventListener(\"touchend\", handleRelease);\n\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleRelease);\n window.removeEventListener(\"touchmove\", handleTouchMove);\n window.removeEventListener(\"touchend\", handleRelease);\n };\n }, [isDragging, calculateRatio, duration, onSeek]);\n\n const displayTime = isDragging ? dragProgress * duration : currentTime;\n\n return (\n <div className=\"pp-seekbar-wrapper\" aria-label=\"Audio progress\">\n <span className=\"pp-time pp-time-current\">{formatTime(displayTime)}</span>\n\n <div\n ref={trackRef}\n className={\"pp-seekbar-track \" + (isDragging ? \"pp-seekbar-dragging\" : \"\")}\n onMouseDown={handlePointerDown}\n onTouchStart={handleTouchStart}\n onKeyDown={handleKeyDown}\n role=\"slider\"\n tabIndex={0}\n aria-valuemin={0}\n aria-valuemax={duration || 100}\n aria-valuenow={Math.round(displayTime)}\n aria-valuetext={formatTime(displayTime)}\n >\n <div\n className=\"pp-seekbar-fill\"\n style={{ width: (progress * 100) + \"%\" }}\n />\n <div\n className=\"pp-seekbar-thumb\"\n style={{ left: (progress * 100) + \"%\" }}\n />\n </div>\n\n <span className=\"pp-time pp-time-total\">{formatTime(duration)}</span>\n </div>\n );\n}\n","import type { PillLabels, PillIcons } from \"../types\";\nimport { CloseIcon } from \"./Icons\";\n\nexport interface PlayerHeaderProps {\n labels: PillLabels;\n icons?: PillIcons;\n onClose: () => void;\n}\n\nexport function PlayerHeader({ labels, icons, onClose }: PlayerHeaderProps) {\n return (\n <div className=\"pp-card-header\">\n <span className=\"pp-telemetry-badge\">{labels.badge}</span>\n <button\n type=\"button\"\n className=\"pp-icon-btn\"\n onClick={onClose}\n aria-label={labels.closePlayer}\n title={labels.closePlayer}\n >\n {icons?.close ?? <CloseIcon size={14} />}\n </button>\n </div>\n );\n}\n","import type { AudioTrack, PillLabels } from \"../types\";\n\nexport interface TrackInfoProps {\n currentTrack?: AudioTrack;\n labels: PillLabels;\n}\n\nexport function TrackInfo({ currentTrack, labels }: TrackInfoProps) {\n return (\n <div className=\"pp-track-info\">\n <div className=\"pp-track-meta\">\n {currentTrack?.genre && (\n <span className=\"pp-genre-badge\">{currentTrack.genre}</span>\n )}\n {currentTrack?.bpm && (\n <span className=\"pp-bpm-badge\">• {currentTrack.bpm}</span>\n )}\n </div>\n\n <p className=\"pp-track-title\" title={currentTrack?.title}>\n {currentTrack?.title || \"No track selected\"}\n </p>\n\n <p className=\"pp-track-subtitle\">\n {currentTrack?.artist ? `${currentTrack.artist} • ${labels.subtitle}` : labels.subtitle}\n </p>\n </div>\n );\n}\n","import type { PillLabels, PillIcons } from \"../types\";\nimport {\n PlayIcon,\n PauseIcon,\n SkipBackIcon,\n SkipForwardIcon,\n VolumeUpIcon,\n VolumeMuteIcon,\n ExternalLinkIcon,\n} from \"./Icons\";\n\nexport interface PlayerControlsProps {\n isPlaying: boolean;\n isMuted: boolean;\n externalLinkUrl?: string;\n labels: PillLabels;\n icons?: PillIcons;\n onPrev: () => void;\n onTogglePlay: () => void;\n onNext: () => void;\n onToggleMute: () => void;\n}\n\nexport function PlayerControls({\n isPlaying,\n isMuted,\n externalLinkUrl,\n labels,\n icons,\n onPrev,\n onTogglePlay,\n onNext,\n onToggleMute,\n}: PlayerControlsProps) {\n return (\n <div className=\"pp-controls-row\">\n <button\n type=\"button\"\n className=\"pp-ctrl-btn\"\n onClick={onPrev}\n aria-label={labels.prevTrack}\n title={labels.prevTrack}\n >\n {icons?.prev ?? <SkipBackIcon size={16} />}\n </button>\n\n <button\n type=\"button\"\n className=\"pp-ctrl-btn-main\"\n onClick={onTogglePlay}\n aria-label={isPlaying ? labels.pause : labels.play}\n >\n {isPlaying\n ? (icons?.pause ?? <PauseIcon size={14} />)\n : (icons?.play ?? <PlayIcon size={14} />)}\n <span>{isPlaying ? labels.pause : labels.play}</span>\n </button>\n\n <button\n type=\"button\"\n className=\"pp-ctrl-btn\"\n onClick={onNext}\n aria-label={labels.nextTrack}\n title={labels.nextTrack}\n >\n {icons?.next ?? <SkipForwardIcon size={16} />}\n </button>\n\n <button\n type=\"button\"\n className=\"pp-ctrl-btn\"\n onClick={onToggleMute}\n aria-label={isMuted ? labels.unmute : labels.mute}\n title={isMuted ? labels.unmute : labels.mute}\n >\n {isMuted\n ? (icons?.unmute ?? <VolumeMuteIcon size={16} />)\n : (icons?.mute ?? <VolumeUpIcon size={16} />)}\n </button>\n\n {externalLinkUrl && (\n <a\n href={externalLinkUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"pp-ctrl-btn\"\n aria-label={labels.listenExternal}\n title={labels.listenExternal}\n >\n {icons?.external ?? <ExternalLinkIcon size={15} />}\n </a>\n )}\n </div>\n );\n}\n","import type { AudioTrack, EmbedMode, PillLabels } from \"../types\";\n\nexport interface ProviderEmbedsProps {\n isLoaded: boolean;\n embedMode: EmbedMode;\n currentTrack?: AudioTrack;\n labels: PillLabels;\n\n // SoundCloud\n isSoundCloud: boolean;\n soundCloudIframeSrc: string;\n scIframeRef: any;\n onSoundCloudLoad: () => void;\n\n // YouTube\n isYouTube: boolean;\n youTubeIframeSrc: string;\n ytIframeRef: any;\n onYouTubeLoad: () => void;\n\n // Mixcloud\n iframeSrc: string;\n iframeRef: any;\n onMixcloudLoad: () => void;\n}\n\nexport function ProviderEmbeds({\n isLoaded,\n embedMode,\n currentTrack,\n labels,\n isSoundCloud,\n soundCloudIframeSrc,\n scIframeRef,\n onSoundCloudLoad,\n isYouTube,\n youTubeIframeSrc,\n ytIframeRef,\n onYouTubeLoad,\n iframeSrc,\n iframeRef,\n onMixcloudLoad,\n}: ProviderEmbedsProps) {\n if (!isLoaded || !currentTrack) return null;\n\n const title = (currentTrack.code || \"\") + \" \" + currentTrack.title;\n const isSeamless = embedMode === \"seamless\";\n const isThemed = embedMode === \"themed\";\n\n return (\n <>\n {/* SoundCloud Embed */}\n {isSoundCloud && soundCloudIframeSrc && (\n isSeamless ? (\n <div className=\"pp-iframe-seamless\" aria-hidden=\"true\">\n <iframe\n ref={scIframeRef}\n tabIndex={-1}\n title={title}\n src={soundCloudIframeSrc}\n allow=\"autoplay\"\n onLoad={onSoundCloudLoad}\n />\n </div>\n ) : (\n <div className=\"pp-iframe-wrapper\">\n <iframe\n ref={scIframeRef}\n title={title}\n className=\"pp-mixcloud-iframe\"\n src={soundCloudIframeSrc}\n allow=\"autoplay\"\n onLoad={onSoundCloudLoad}\n />\n </div>\n )\n )}\n\n {/* YouTube Embed */}\n {isYouTube && youTubeIframeSrc && (\n isSeamless ? (\n <div className=\"pp-iframe-seamless\" aria-hidden=\"true\">\n <iframe\n ref={ytIframeRef}\n tabIndex={-1}\n title={title}\n src={youTubeIframeSrc}\n allow=\"autoplay; encrypted-media\"\n onLoad={onYouTubeLoad}\n />\n </div>\n ) : (\n <div className={\"pp-iframe-wrapper \" + (isThemed ? \"pp-iframe-themed\" : \"\")}>\n <iframe\n ref={ytIframeRef}\n title={title}\n className=\"pp-mixcloud-iframe\"\n src={youTubeIframeSrc}\n allow=\"autoplay; encrypted-media\"\n onLoad={onYouTubeLoad}\n />\n </div>\n )\n )}\n\n {/* Mixcloud Embed */}\n {Boolean(currentTrack.feed) && (\n isSeamless ? (\n <div className=\"pp-iframe-seamless\" aria-hidden=\"true\">\n <iframe\n ref={iframeRef}\n tabIndex={-1}\n title={title}\n className=\"pp-mixcloud-iframe\"\n src={iframeSrc}\n allow=\"autoplay; encrypted-media; fullscreen; picture-in-picture\"\n onLoad={onMixcloudLoad}\n />\n </div>\n ) : (\n <>\n <div className={\"pp-iframe-wrapper \" + (isThemed ? \"pp-iframe-themed\" : \"\")}>\n <iframe\n ref={iframeRef}\n title={title}\n className=\"pp-mixcloud-iframe\"\n src={iframeSrc}\n allow=\"autoplay; encrypted-media; fullscreen; picture-in-picture\"\n onLoad={onMixcloudLoad}\n />\n </div>\n <span className=\"pp-iframe-hint\">{labels.directPlayHint}</span>\n </>\n )\n )}\n </>\n );\n}\n"],"mappings":"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","names":["useState","useEffect","useRef","useCallback","useState","useEffect","useRef","useCallback","useRef","useEffect","useCallback","useRef","useEffect","useCallback","useRef","useEffect","useCallback","useState","useEffect","useRef","useCallback","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useRef","useCallback","useEffect","jsx","jsxs","useState","useRef","useCallback","useEffect","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useEffect","useRef","useCallback"]}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@stargate91/pill-player",
3
+ "version": "0.1.0",
4
+ "description": "Futuristic HUD cyber audio player with 16-band DSP spectrum visualizer and collapsible floating pill widget.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./dist/index.css": "./dist/index.css"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "assets"
19
+ ],
20
+ "scripts": {
21
+ "dev": "vite",
22
+ "build": "tsup",
23
+ "build:demo": "vite build",
24
+ "preview": "vite preview",
25
+ "typecheck": "tsc --noEmit",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "keywords": [
29
+ "audio-player",
30
+ "hud",
31
+ "cyberpunk",
32
+ "spectrum-visualizer",
33
+ "react-audio-player",
34
+ "web-audio-api",
35
+ "floating-widget"
36
+ ],
37
+ "author": "Levente Gall <https://leventegall.dev>",
38
+ "license": "MIT",
39
+ "peerDependencies": {
40
+ "react": ">=18.0.0",
41
+ "react-dom": ">=18.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@iconify-json/lucide": "^1.2.130",
45
+ "@types/react": "^18.3.18",
46
+ "@types/react-dom": "^18.3.5",
47
+ "@vitejs/plugin-react": "^4.3.4",
48
+ "lucide-react": "^1.43.0",
49
+ "react": "^18.3.1",
50
+ "react-dom": "^18.3.1",
51
+ "tsup": "^8.3.6",
52
+ "typescript": "^5.7.3",
53
+ "unocss": "^66.10.1",
54
+ "vite": "^6.1.0"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public"
58
+ }
59
+ }