๐ Overview
This is a modern, feature-rich HTML5 audio player built with vanilla JavaScript, featuring a unique circular canvas-based visualizer, comprehensive playlist management, and advanced audio processing capabilities. The application is designed to be lightweight, dependency-free, and fully responsive across all devices.
Key Highlights
- Zero Dependencies: Pure vanilla JavaScript, HTML5, and CSS3
- Circular Visualizer: Real-time audio visualization using HTML5 Canvas
- Advanced Playlist: IndexedDB-powered persistent storage with drag-and-drop reordering
- 10-Band Equalizer: Professional-grade audio equalization with presets
- Playback Speed Control: Adjustable speed from 0.5x to 2x with modal selection
- Shuffle & Repeat: Multiple playback modes (off, one, all)
- Custom Background: Upload or URL-based background images with glassy effect
- Theme System: System-aware light/dark theme switching
- Fully Responsive: Optimized for desktop, tablet, and mobile
- Accessibility: WCAG-compliant with keyboard navigation and ARIA labels
โจ Features
๐จ Circular Visualizer
Real-time audio frequency visualization rendered on HTML5 Canvas with smooth animations and gradient effects. The visualizer responds to audio frequency data using Web Audio API's AnalyserNode.
๐ต Playlist Management
Comprehensive playlist system with IndexedDB persistence, drag-and-drop reordering, track sharing, thumbnail support, and real-time search/filter. Supports both JSON-based and IndexedDB storage.
๐ Search & Filter
Real-time search functionality that filters tracks by song name, artist, or URL as you type. Features keyboard shortcuts (Ctrl+F or /), clear button, and instant results. Perfect for navigating large playlists.
๐ป Radio/Streaming Support
Full support for live radio streams and audio streaming URLs. Automatically detects live streams, displays "LIVE" indicator with pulsing animation, and disables seeking controls. Works with MP3 streams, Icecast, Shoutcast, and other streaming protocols.
๐ค Recording Capabilities
Built-in audio recording using MediaRecorder API. Record audio directly from your microphone, save recordings with custom titles and artist names, and automatically add them to your playlist. Features real-time recording timer and visual indicators.
๐๏ธ 10-Band Equalizer
Professional parametric equalizer with 10 frequency bands (60Hz to 16kHz), adjustable gain (-12dB to +12dB), and preset configurations (Flat, Bass Boost, Treble Boost, Vocal).
๐ Shuffle Mode
Fisher-Yates shuffle algorithm for randomizing track order. Maintains shuffle history and reshuffles when all tracks have been played.
๐ Repeat Modes
Three repeat modes: Off (normal playback), One (single track loop), and All (playlist loop). Visual indicators show current mode.
๐ Theme System
System-aware theme switching with three modes: System (follows OS preference), Light, and Dark. Persists user preference in localStorage.
๐ฑ Responsive Design
Fully responsive layout that adapts to all screen sizes. Touch-optimized controls for mobile devices with gesture support.
โฟ Accessibility
WCAG 2.1 AA compliant with keyboard navigation, ARIA labels, screen reader support, and focus management.
๐พ Persistent Storage
IndexedDB for offline-first architecture. Stores playlists, settings, track metadata, and user preferences with automatic fallback to localStorage.
โก Playback Speed Control
Adjustable playback speed from 0.5x to 2x (0.5x, 0.75x, 1x, 1.25x, 1.5x, 1.75x, 2x). Features a compact modal dialogue with inline icons for quick selection. Speed setting persists across sessions.
๐ผ๏ธ Custom Background Image
Personalize your player with custom background images. Upload image files or use image URLs. Features a glassy/frosted glass effect with adjustable blur and opacity. Background scales responsively with the player UI and persists across sessions.
๐น Keyboard Shortcuts
Comprehensive keyboard controls: Space (play/pause), Arrow keys (seek), S (shuffle), R (repeat), M (mute), T (speed panel), Ctrl+F or / (search), and more.
๐ค Track Sharing
Share individual tracks via URL parameters. Supports deep linking to specific tracks in the playlist.
๐๏ธ Volume Control
Precise volume control with visual feedback, mute functionality, and persistent volume level storage.
๐ผ๏ธ Picture-in-Picture Mode
Floating mini player window that stays on top while browsing. Features native browser PiP support (works across tabs) with fallback to custom floating window. Includes clickable controls for play/pause, previous, and next track. Draggable and position-persistent.
๐ User Guide
This section provides step-by-step instructions on how to use each feature of the audio player.
๐ต Basic Playback
Playing Music
- Open the playlist by clicking the playlist icon (๐) in the top-left corner
- Click on any track in the playlist to start playback
- Use the play/pause button in the center of the player to control playback
- Click the previous (โ) or next (โถ) buttons to navigate between tracks
Seeking Through a Track
- Mouse/Touch: Click or tap anywhere on the circular visualizer to jump to that position
- Keyboard: Press
โ(left arrow) to seek backward 10 seconds, orโ(right arrow) to seek forward 10 seconds
Volume Control
- Hover over the volume icon (๐) at the bottom of the player
- A volume slider will appear
- Drag the slider up to increase volume or down to decrease
- Click the volume icon to mute/unmute
- Keyboard: Press
โto increase volume,โto decrease, orMto mute/unmute
๐๏ธ Using the Equalizer
- Click the equalizer button (๐๏ธ) in the player controls (top-right area)
- The equalizer panel will appear below the player
- Adjust any of the 10 frequency bands by dragging the sliders:
- Move sliders up to boost frequencies (+12dB max)
- Move sliders down to reduce frequencies (-12dB max)
- Use preset buttons for quick configurations:
- Flat: All bands at 0dB (neutral)
- Bass Boost: Enhances low frequencies
- Treble Boost: Enhances high frequencies
- Vocal: Optimizes for vocal clarity
- Click the equalizer button again to close the panel
๐ Shuffle Mode
- Click the shuffle button (๐) in the player controls
- The button will highlight when shuffle is active
- Tracks will play in random order
- Click again to disable shuffle
- Keyboard: Press
Sto toggle shuffle
๐ Repeat Modes
- Click the repeat button (๐) in the player controls
- Cycle through three modes:
- Off: Normal playback, stops at end of playlist
- One: Repeats the current track indefinitely
- All: Repeats the entire playlist
- The button icon changes to indicate the current mode
- Keyboard: Press
Rto cycle through repeat modes
โก Playback Speed Control
- Click the speedometer button (โก) in the player controls
- A speed panel will appear
- Select your desired speed:
- 0.5x (slowest)
- 0.75x
- 1x (normal)
- 1.25x
- 1.5x
- 1.75x
- 2x (fastest)
- The speed setting persists across sessions
- Click the ร button or press
Tto close the speed panel - Keyboard: Press
Tto open/close the speed panel
๐ Playlist Management
Opening the Playlist
- Click the playlist icon (๐) in the top-left corner
- The playlist panel will slide in from the left
- Click outside the panel or press
Escapeto close
Adding Tracks
- Open the playlist panel
- Click the "Add Track" button (usually at the top)
- Choose one of two methods:
- From URL: Enter the track URL, song name, and artist name
- From File: Click "Choose File" and select an audio file from your device
- Click "Add" to add the track to your playlist
Reordering Tracks (Drag and Drop)
- Open the playlist panel
- Desktop: Click and hold the drag handle (โฎโฎ) on the left of a track, drag it to the desired position, and release
- Mobile: Touch and hold the drag handle, drag to the desired position, and release
- The new order is automatically saved
Searching/Filtering Tracks
- Open the playlist panel
- Click in the search box at the top of the playlist
- Type to filter tracks by:
- Song name
- Artist name
- URL
- Results update in real-time as you type
- Click the ร button to clear the search
- Keyboard: Press
Ctrl+For/to focus the search box
Deleting Tracks
- Open the playlist panel
- Hover over a track to reveal the delete button (๐๏ธ)
- Click the delete button
- Confirm deletion if prompted
Downloading Tracks
- Open the playlist panel
- Hover over a track to reveal the download button (โฌ๏ธ)
- Click the download button
- The track will download to your device
Sharing Tracks
- Open the playlist panel
- Click the share button (๐) on any track
- The track URL will be copied to your clipboard
- Share the URL with others - they can open it to play that specific track
๐ค Recording Audio
- Click the record button (๐ค) in the player controls
- The recording panel will appear
- Click "Start" to begin recording
- Speak or play audio into your microphone
- While recording, you can:
- Click "Pause" to pause recording (click "Resume" to continue)
- Click "Finish" when done recording
- Click "Cancel" to discard the recording
- After finishing, a save dialog will appear
- Enter a song name and artist name
- Click "Save" to add the recording to your playlist
- The recording will appear in your playlist automatically
๐ป Listening to Radio/Streams
- Add a streaming URL to your playlist (same as adding a regular track)
- Click on the stream in your playlist
- The player will automatically detect it's a live stream
- A "LIVE" indicator will appear instead of the time display
- Seeking controls are automatically disabled for live streams
- Use play/pause and volume controls normally
๐ Changing Theme
- Look for the theme buttons in the top-right corner
- Click one of three options:
- System: Follows your operating system's theme preference
- Light: Always use light theme
- Dark: Always use dark theme
- Your preference is saved automatically
๐ผ๏ธ Custom Background Image
- Open the playlist panel
- Click the settings/gear icon (โ๏ธ) to open settings
- Find the "Background Image" section
- Choose one of two methods:
- From URL: Switch to "URL" tab, enter an image URL, and click "Apply Background"
- Upload File: Switch to "Upload" tab, click "Choose File", select an image, and click "Apply Background"
- A preview will appear - adjust if needed
- Click "Apply Background" to set the background
- The background will appear with a glassy blur effect
- Click "Clear" to remove the background image
๐ผ๏ธ Picture-in-Picture Mode
Picture-in-Picture (PiP) mode allows you to have a floating mini player window that stays visible while you browse other tabs or work in other applications.
Opening PiP Mode
- Click the Picture-in-Picture button (๐ผ๏ธ) in the player controls (bottom of the player)
- A floating window will appear with track information and controls
- The window can be dragged around the screen by clicking and dragging the header
Using PiP Controls
- Previous Button (โ): Go to the previous track
- Play/Pause Button (โถ/โธ): Control playback
- Next Button (โถ): Go to the next track
- Close Button (ร): Close the PiP window
PiP Features
- Native Browser PiP: On supported browsers, uses native Picture-in-Picture API for cross-tab support
- Custom Floating Window: Fallback mode with fully clickable buttons
- Position Memory: Remembers window position between sessions
- Real-time Updates: Track info, time, and play state update automatically
- Draggable: Click and drag the header to move the window
Closing PiP Mode
- Click the close button (ร) in the top-right corner of the PiP window, or
- Click the Picture-in-Picture button again in the player controls
โ๏ธ Settings
Accessing Settings
- Open the playlist panel
- Click the settings/gear icon (โ๏ธ)
- The settings panel will appear
Available Settings
- Playback: Auto advance on end, loop current track, auto play on track select
- Player control buttons: Show or hide each control (Shuffle, Repeat, Equalizer, Speed, Record, Picture-in-Picture) individually; changes apply and persist immediately
- Theme: System, Light, or Dark
- Volume: Default volume level
- Background Image: Set a custom background via URL or file upload (see above)
- Data Management: Clear Database to remove all stored data (playlists, settings, recordings)
Save Settings
The Save Settings button appears in a dedicated footer at the bottom of the settings form, separated by a border from the sections above. It applies to all settings (playback, player buttons, theme, volume, background image). Use it after changing any options to persist them.
Background Image section (From URL tab)
In the Background Image section, the From URL tab shows a text input for the image URL and a Load from URL button. The input is styled as a text field (lighter background, normal text), and the button is styled as a primary action (accent color, prominent) so the two are clearly distinct.
๐น Keyboard Shortcuts
Use these keyboard shortcuts for quick access to features:
| Key | Action |
|---|---|
Space |
Play/Pause |
โ |
Seek backward 10 seconds |
โ |
Seek forward 10 seconds |
โ |
Increase volume |
โ |
Decrease volume |
M |
Mute/Unmute |
S |
Toggle shuffle |
R |
Cycle repeat mode |
T |
Open/close speed panel |
Ctrl+F or / |
Focus playlist search (when playlist is open) |
Escape |
Close playlist panel or modals |
Ctrl+Space (in PiP) |
Play/Pause (when Picture-in-Picture window is active) |
Ctrl+โ or Ctrl+N (in PiP) |
Next track (when Picture-in-Picture window is active) |
Ctrl+โ or Ctrl+P (in PiP) |
Previous track (when Picture-in-Picture window is active) |
๐ก Tips & Tricks
- Quick Track Selection: Click directly on a track in the playlist to start playing it
- Visual Feedback: The circular visualizer shows real-time audio frequency data - watch it react to the music!
- Persistent Settings: Your equalizer settings, playback speed, and theme preference are saved automatically
- Mobile Optimization: On mobile devices, use touch gestures for drag-and-drop reordering
- Offline Playback: Tracks stored in IndexedDB can be played offline
- Large Playlists: Use the search feature to quickly find tracks in large playlists
- Recording Quality: Recordings are saved in WebM/Opus format for good quality and file size
- Background Images: Images are automatically compressed when uploaded to save storage space
โ Troubleshooting
Audio Not Playing
- Check your browser's console for errors (F12 โ Console tab)
- Ensure the audio file URL is accessible and not blocked by CORS
- Try a different audio format (MP3, OGG, WAV)
- Check your browser's autoplay policies - some browsers require user interaction first
Recording Not Working
- Grant microphone permissions when prompted
- Check your browser's privacy settings for microphone access
- Ensure you're using HTTPS (required for MediaRecorder API in most browsers)
Playlist Not Saving
- Check if IndexedDB is supported in your browser
- Check browser storage quota - clear some space if needed
- Try clearing browser cache and reloading
Visualizer Not Showing
- Ensure audio is actually playing
- Check if Web Audio API is supported in your browser
- Try refreshing the page
๐๏ธ Architecture
System Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HTML5 Audio Element โ
โ (Media Source) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Web Audio API Graph โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโ โ
โ โ Equalizerโโ โ Gain โโ โ Analyser โโ โ Out โ โ
โ โ Filters โ โ Node โ โ Node โ โ โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Canvas Visualizer โ
โ (Circular Frequency Display) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Playlist System โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ IndexedDBโ โ JSON โ โ Controls โ โ
โ โ Storage โ โ Fallback โ โ & UI โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Core Components
1. Player Engine (player.js)
The main audio playback engine that handles:
- HTML5 Audio element management
- Web Audio API graph construction
- Equalizer filter chain
- Volume control via GainNode
- Audio analysis via AnalyserNode
- Playback state management
- Playback speed control (0.5x - 2x)
- Live stream detection and handling
- Audio recording via MediaRecorder API
- Shuffle and repeat logic
2. Visualizer (player.js - Framer, Tracker, Scene)
Canvas-based visualization system:
- Scene: Canvas setup and coordinate system
- Framer: Circular tick marks and loading indicator
- Tracker: Frequency bars visualization
- Controls: Play/pause button visualization
3. Playlist System (playlist.js)
Comprehensive playlist management:
- Track loading from JSON or IndexedDB
- Drag-and-drop reordering
- Track addition/removal
- Real-time search and filtering
- Thumbnail management
- Share functionality
- UI rendering and interaction
4. Storage Layer (idb.js)
IndexedDB wrapper for persistent storage:
- Track metadata storage
- Playlist order management
- Blob storage for uploaded files
- State persistence
- Automatic migration and fallback
5. Theme System (theme.js)
Dynamic theme management:
- System preference detection
- Light/dark theme switching
- CSS variable management
- Preference persistence
6. Recording System (recording.js)
Audio recording functionality:
- MediaRecorder API integration
- Microphone access and permissions
- Recording state management (start, pause, resume, stop)
- Real-time recording timer
- WebM/Opus format encoding
- Recording save dialog and metadata input
- Automatic playlist integration
7. UI Components (script.js)
User interface utilities:
- Toast notifications
- Modal dialogs
- Responsive scaling
- Event handling
8. Picture-in-Picture System (pip.js)
Floating mini player window:
- Native browser Picture-in-Picture API integration
- Custom floating window fallback
- Canvas-based visual display with track info and visualizer
- Drag-and-drop window positioning
- Position persistence in localStorage
- Real-time synchronization with main player
- Clickable controls (play/pause, previous, next)
๐ File Structure
The project follows a clean, organized structure with clear separation of concerns:
Core Files Overview
๐ index.html
Purpose: Main HTML structure
Size: ~15 KB
Contains:
- Player UI structure
- SVG icon sprites
- Equalizer panel
- Playlist panel
๐จ style.css
Purpose: All styling
Size: ~80 KB
Contains:
- Theme variables
- Responsive design
- Animations & transitions
- Component styles
๐ต player.js
Purpose: Core audio engine
Size: ~65 KB
Contains:
- Audio playback logic
- Canvas visualizer
- Equalizer system
- Playback speed control
- Shuffle & repeat
๐ playlist.js
Purpose: Playlist management
Size: ~95 KB
Contains:
- Track management
- Search and filtering
- Drag-and-drop
- UI rendering
- Share functionality
๐พ idb.js
Purpose: Storage layer
Size: ~15 KB
Contains:
- IndexedDB wrapper
- Track storage
- State persistence
- Blob management
๐ theme.js
Purpose: Theme system
Size: ~3 KB
Contains:
- Theme switching
- CSS variable management
- System preference detection
- Preference persistence
๐ค recording.js
Purpose: Audio recording
Size: ~15 KB
Contains:
- MediaRecorder API integration
- Recording controls
- Timer and state management
- Save dialog and metadata
๐ผ๏ธ pip.js
Purpose: Picture-in-Picture system
Size: ~18 KB
Contains:
- Native browser PiP API integration
- Custom floating window fallback
- Canvas-based visual display
- Drag-and-drop positioning
- Position persistence
- Real-time player synchronization
๐ ๏ธ script.js
Purpose: UI utilities
Size: ~5 KB
Contains:
- Toast notifications
- Modal dialogs
- Responsive scaling
- Event handling
๐ playlist.json
Purpose: Default playlist
Size: ~1 KB
Contains:
- Track metadata
- Playlist configuration
- Default settings
Directory Structure
Stylesheets including theme definitions, responsive breakpoints, and component styles.
Core JavaScript modules:
player.js- Audio playback and visualizationplaylist.js- Playlist management and UIidb.js- Persistent storage layerrecording.js- Audio recording systempip.js- Picture-in-Picture floating windowtheme.js- Theme managementscript.js- UI utilities and helpers
Configuration files including the default playlist JSON.
Audio files directory. Supports MP3, OGG, and WAV formats.
Custom font files (Rajdhani) for consistent typography.
SVG icon library (Bootstrap Icons) embedded inline for performance.
โ๏ธ Configuration
Playlist Configuration (playlist.json)
Track entries can be single audio files or M3U playlists (one playlist = one row; the player plays through its entries in order). Use "url" ending in .m3u/.m3u8 or add "isM3u": true for M3U.
{
"version": 1,
"autoplayOnSelect": true,
"tracks": [
{
"artist": "Playlist",
"song": "Demo playlist (M3U)",
"url": "assets/tracks/demo-playlist.m3u",
"thumbnail": "optional-image-url.jpg"
},
{
"artist": "Artist Name",
"song": "Song Title",
"url": "path/to/track.mp3",
"thumbnail": "optional-image-url.jpg"
}
]
}
๐ M3U Playlist Support
The player supports M3U / M3U8 playlists as a single playlist entry. When you load or select an M3U track, the player fetches the file, parses the list of entries, and plays them in order (next/previous move through the M3U entries, then the main playlist).
M3U from URL (e.g. playlist.json)
- Use a track with
urlending in.m3uor.m3u8, or setisM3u: true. - Relative paths in the M3U file are resolved against the M3U URL. Keep entry paths (e.g. filenames only) in the same folder as the M3U for correct resolution.
- M3U URLs are prefetched when the playlist is applied so that selecting an M3U can start playback immediately (same user gesture).
Uploaded M3U (with audio files)
- Upload the M3U file and all its audio files together (same selection). The app matches M3U entries to uploaded files by filename and creates one playlist entry for the M3U.
- Resolved entries are stored in IndexedDB as Blobs (
m3uResolvedEntries), so the uploaded M3U playlist works after page refresh and when switching to another track and back. - If you upload only the M3U (no audio files), youโll see a message to upload the M3U together with its audio files. M3U entries that are absolute URLs (http/https) are still used when present.
Auto-play on select
When โAuto play on trackโ is enabled in Settings, selecting a track (including an M3U) starts playback. For M3U from URL, prefetch ensures the list is ready so playback can start on first select. If the browser blocks autoplay, the next click or key press will start playback.
Player Settings
Settings are stored in localStorage and can be modified programmatically:
Player.settings = {
autoPlay: false, // Auto-play on load
autoAdvance: false, // Auto-advance to next track
repeatMode: 'off', // 'off' | 'one' | 'all'
shuffle: false // Enable shuffle mode
}
Theme Configuration
Themes are managed via CSS variables in style.css:
:root {
--accent: #FE4365; // Primary accent color
--neutral: #F5F5F5; // Neutral color
--accent-rgb: 254, 67, 101; // RGB values for rgba()
// Theme-specific variables are set dynamically
// via JavaScript based on user preference
}
Equalizer Configuration
Equalizer bands are configured in player.js:
var frequencies = [
60, // 60Hz - Sub-bass
170, // 170Hz - Bass
310, // 310Hz - Low-mid
600, // 600Hz - Mid
1000, // 1kHz - Upper-mid
3000, // 3kHz - Presence
6000, // 6kHz - Brilliance
12000, // 12kHz - High
14000, // 14kHz - Very high
16000 // 16kHz - Ultra high
];
Background Image Configuration
Custom background images can be set through the Settings panel. The Save Settings button is in a separate footer below all sections (including Background Image), so it is clear that it saves all settings. In the Background Image From URL tab, the URL input is styled as a text field and the Load from URL button as a primary action for clarity. The feature supports:
- Image URLs: Enter any publicly accessible image URL
- File Upload: Upload image files directly from your device
- Glassy Effect: Automatic frosted glass effect with adjustable blur and opacity
- Responsive Scaling: Background scales with the player UI
- Persistence: Background image is saved to IndexedDB (or localStorage fallback)
Background images are stored in IndexedDB under the key 'backgroundImage'. You can
programmatically set or clear the background:
// Set background image from URL
Playlist.setBackgroundImage('https://example.com/image.jpg');
// Set background image from data URL (file upload)
Playlist.setBackgroundImage('data:image/jpeg;base64,...');
// Clear background image
Playlist.clearBackgroundImage();
// Load current background image
Playlist.loadBackgroundImage().then(function(url) {
console.log('Current background:', url);
});
--bg-blur: Blur intensity (default: 50px)--bg-opacity: Opacity level (default: 0.18)--bg-scale: Scale factor (default: 1.15)--player-scale: Player UI scale (synced automatically)
๐ API Reference
Player API
Playback Control
| Method | Description | Parameters |
|---|---|---|
Player.play() |
Start playback | None |
Player.pause() |
Pause playback | None |
Player.togglePlay() |
Toggle play/pause | None |
Player.loadTrack(index, options) |
Load track by index; optionally autoplay when ready | index (number), options (optional) e.g. { autoplay: true } |
Player.prefetchM3uUrls(tracks) |
Preload M3U playlists for the given tracks (URL-based only) | tracks (array of track objects) |
Player.cacheM3uEntries(m3uUrl, entries) |
Store resolved M3U entries for a given M3U URL (e.g. after upload) | m3uUrl (string), entries (array of { artist, song, url }) |
Player.nextTrack() |
Play next track | None |
Player.prevTrack() |
Play previous track | None |
Equalizer API
| Method | Description | Parameters |
|---|---|---|
Player.setEqualizerBand(band, gain) |
Set gain for specific band | band (0-9), gain (-12 to 12 dB) |
Player.setEqualizerEnabled(enabled) |
Enable/disable equalizer | enabled (boolean) |
Player.applyEqualizerPreset(preset) |
Apply preset configuration | preset ('flat'|'bass'|'treble'|'vocal') |
Shuffle & Repeat API
| Method | Description | Parameters |
|---|---|---|
Player.toggleShuffle() |
Toggle shuffle mode | None |
Player.setRepeatMode(mode) |
Set repeat mode | mode ('off'|'one'|'all') |
Player.cycleRepeatMode() |
Cycle through repeat modes | None |
Playback Speed API
| Method | Description | Parameters |
|---|---|---|
Player.setPlaybackSpeed(speed) |
Set playback speed | speed (0.5 - 2.0) |
Player.cyclePlaybackSpeed() |
Cycle through speed options | None |
Player.updateSpeedUI() |
Update speed control UI | None |
Playlist API
| Method | Description | Parameters |
|---|---|---|
Playlist.load() |
Load playlist from storage | None |
Playlist.addByUrl(url, song, artist, thumbnail, thumbnailBlob, options) |
Add track by URL; options can include { isM3u: true } or { isM3u: true, m3uResolvedEntries: [...] } for M3U with persisted entries (Blobs in IndexedDB) |
url, song, artist (strings); thumbnail, thumbnailBlob (optional); options (optional) |
Playlist.addFile(file, song, artist) |
Add track from file | file (File object), song, artist |
Playlist.deleteTrackById(id) |
Delete track by ID | id (number) |
Playlist.reorderTracks(draggedId, dropId, insertBefore) |
Reorder tracks via drag-and-drop | draggedId, dropId (numbers), insertBefore (boolean) |
Playlist.renderList() |
Render playlist list with optional filtering | None (reads search input automatically) |
Playlist.initSearchInput() |
Initialize search input handlers | None |
Playlist.setBackgroundImage(url) |
Set custom background image | url (string - image URL or data URL) |
Playlist.clearBackgroundImage() |
Remove background image | None |
Playlist.loadBackgroundImage() |
Load background image from storage | None (returns Promise) |
Playlist.applyBackgroundImage(url) |
Apply background image to UI | url (string) |
Background Image API
The background image feature allows users to customize the player's background with a glassy/frosted glass effect:
- Image Sources: Supports both image URLs and uploaded files (converted to data URLs)
- Storage: Background image URL is stored in IndexedDB under key
'backgroundImage' - Visual Effect: Automatic glassy effect with blur, brightness, and saturation filters
- Responsive: Background scales with player UI using CSS custom properties
- Theme Aware: Overlay adjusts for light/dark themes
Example usage:
// Set background from URL
Playlist.setBackgroundImage('https://example.com/background.jpg');
// Set background from uploaded file (data URL)
var fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
Playlist.setBackgroundImage(e.target.result);
};
reader.readAsDataURL(file);
});
// Clear background
Playlist.clearBackgroundImage();
// Load existing background
Playlist.loadBackgroundImage().then(function(url) {
if (url) {
console.log('Background loaded:', url);
}
});
Search Functionality
The search feature automatically filters tracks as you type in the search input. It searches across:
- Song/track names
- Artist names
- Track URLs
The search is case-insensitive and updates in real-time. Use Ctrl+F or
/ to focus the search input when the playlist is open.
Streaming Support
The player automatically detects and handles live radio streams:
- Live Stream Detection: Detects streams with infinite or unknown duration
- UI Indicators: Shows "LIVE" text with pulsing animation instead of time
- Seeking Disabled: Automatically disables seeking controls for live streams
- Supported Formats: MP3 streams, Icecast, Shoutcast, and other HTTP/HTTPS audio streams
- CORS Support: Handles cross-origin streams with proper CORS headers
To add a radio stream, simply add it to your playlist with a streaming URL:
{
"artist": "Radio Station",
"song": "Live Stream",
"url": "https://stream.example.com/radio.mp3"
}
Storage API (PlaylistStore)
| Method | Description | Parameters |
|---|---|---|
PlaylistStore.init() |
Initialize IndexedDB | None |
PlaylistStore.load() |
Load all data from IndexedDB | None |
PlaylistStore.setState(key, value) |
Store state value | key (string), value (any) |
PlaylistStore.getState(key) |
Retrieve state value | key (string) |
๐พ Database System
IndexedDB Overview
This application uses IndexedDB (Indexed Database API) as its primary storage mechanism. IndexedDB is a low-level API for client-side storage of significant amounts of structured data, including files/blobs.
- A browser-native NoSQL database that runs in the browser
- Stores data asynchronously using object stores
- Supports transactions, indexes, and large binary data (blobs)
- Part of the HTML5 specification, supported by all modern browsers
Database Schema
The application uses a single IndexedDB database named 'circular-player-db' with the
following structure:
Database: 'circular-player-db'
Version: 1
Object Stores:
1. 'tracks'
- Key: id (auto-increment)
- Index: url (unique)
- Fields: artist, song, url, blob, mime, thumbnail, thumbnailBlob, isLiveStream
2. 'state'
- Key: key (string)
- Fields: value (any type)
- Common keys: 'playlistOrder', 'lastTrackId', 'autoplayOnSelect', 'backgroundImage'
3. 'files'
- Key: id (auto-increment)
- Fields: blob (Blob object), mime (string), size (number)
- Used for: Storing uploaded audio files and recordings
Safety & Security Considerations
- Client-Side Only: IndexedDB is a client-side database. All data is stored locally in the user's browser and is NOT sent to any server automatically.
- Browser Storage Limits: Each browser has storage quotas (typically 50-60% of total disk space). The application does not enforce size limits, so users should be aware of storage usage.
- Data Persistence: Data persists until explicitly cleared by the user or browser settings. Users can clear IndexedDB data through browser developer tools or settings.
- Same-Origin Policy: IndexedDB follows the same-origin policy. Data stored by one origin cannot be accessed by another origin.
- No Encryption: Data stored in IndexedDB is NOT encrypted by default. Sensitive information should not be stored without additional encryption.
- Private/Incognito Mode: In private browsing mode, IndexedDB data is cleared when the session ends.
Data Storage Details
What Gets Stored:
- Playlist Tracks: Track metadata (artist, song, URL), audio file blobs, thumbnails
- Playlist Order: Custom track ordering from drag-and-drop
- User Preferences: Theme preference, autoplay settings, background image URLs
- Recordings: Audio recordings saved by users (stored as Blob objects)
- State Data: Last played track, playlist order, various settings
Storage Size Considerations:
- Audio Files: Uploaded audio files are stored as Blob objects. Large files will consume significant storage space.
- M3U Resolved Entries: For uploaded M3U playlists (M3U + audio files added together), the resolved list of audio Blobs is stored in the track as
m3uResolvedEntriesso playback persists after refresh. - Recordings: Audio recordings are stored in WebM/Opus format. Recording length directly affects storage size.
- Thumbnails: Image thumbnails are compressed to ~500KB maximum before storage.
- Background Images: Background images are stored as data URLs, which can be large for high-resolution images.
Best Practices & Cautions
- Regular Cleanup: Use the "Clear Database" feature in Settings to remove all stored data when needed.
- Monitor Storage: Check browser storage usage periodically to avoid quota issues.
- Backup Important Data: Export playlists or important tracks before clearing data.
- Understand Limitations: Be aware that IndexedDB data is local to the browser and device.
- Data Loss Risk: Clearing browser data, using private mode, or uninstalling the browser will delete all stored data.
- No Cloud Sync: This application does NOT sync data to cloud services. Data is only stored locally.
- Cross-Device Limitation: Data stored on one device/browser is NOT accessible on another device.
- Browser Compatibility: While IndexedDB is widely supported, some older browsers may not support it fully.
- Quota Exceeded: If storage quota is exceeded, operations may fail silently. The application includes error handling but users should monitor storage.
- Large File Handling: Very large audio files may cause performance issues or storage quota problems.
Error Handling
The application includes error handling for common IndexedDB scenarios:
- Database Initialization Failures: Falls back to JSON-based playlist loading
- Storage Quota Exceeded: Shows error notifications to users
- Transaction Failures: Includes try-catch blocks and error callbacks
- Browser Support Detection: Checks for IndexedDB support before attempting operations
Data Migration & Compatibility
The application handles database versioning and migration:
- Version Management: Uses IndexedDB versioning system for schema updates
- Backward Compatibility: Maintains compatibility with existing data structures
- Fallback Mechanisms: Falls back to localStorage and JSON files if IndexedDB is unavailable
Privacy Considerations
- All data is stored locally on the user's device
- No data is transmitted to external servers unless explicitly shared by the user
- Users have full control over their data through browser settings
- Recordings and uploaded files are stored only on the local device
- Background images from URLs may be fetched from external servers (standard browser behavior)
Clearing Database
Users can clear all stored data through:
- Application Settings: Use the "Clear Database" button in the Settings panel
- Browser Developer Tools: Application โ Storage โ IndexedDB โ Delete database
- Browser Settings: Clear browsing data โ Select "IndexedDB" โ Clear
๐ง Technical Details
Web Audio API Graph
The audio processing pipeline:
MediaElementAudioSourceNode (HTML5 Audio)
โ
BiquadFilterNode (Equalizer Band 1)
โ
BiquadFilterNode (Equalizer Band 2)
โ
... (8 more bands)
โ
GainNode (Volume Control)
โ
AnalyserNode (Frequency Analysis)
โ
AudioDestinationNode (Output)
Visualizer Algorithm
The circular visualizer uses:
- AnalyserNode.getByteFrequencyData(): Gets frequency data (0-255 values)
- Circular Coordinate System: Converts frequency data to radial positions
- Gradient Rendering: Uses Canvas gradients for visual appeal
- RequestAnimationFrame: Smooth 60fps animation loop
- Dynamic Scaling: Adapts to screen size and DPI
Shuffle Algorithm
Uses Fisher-Yates shuffle for true randomization:
function generateShuffleOrder() {
var order = [];
for (var i = 0; i < tracks.length; i++) {
order.push(i);
}
// Fisher-Yates shuffle
for (var i = order.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = order[i];
order[i] = order[j];
order[j] = temp;
}
return order;
}
Drag-and-Drop Implementation
Cross-platform drag-and-drop with robust mobile support:
- Desktop: Mouse events (mousedown, mousemove, mouseup) with visual drag indicators
- Mobile: Touch events (touchstart, touchmove, touchend) with improved drop detection
- Visual Feedback: translateY transform for smooth movement with drag indicators (dragOverBefore/dragOverAfter)
- Drop Detection: Multiple fallback strategies using elementFromPoint() API and position-based detection for reliable mobile reordering
- Persistence: Updates IndexedDB playlistOrder array with proper error handling
- Mobile Optimization: Enhanced touch handling with improved threshold detection (3x item height) and multiple fallback mechanisms to ensure reordering persists
IndexedDB Schema
Database: 'circular-player-db'
Version: 1
Object Stores:
1. 'tracks'
- Key: id (auto-increment)
- Index: url (unique)
- Fields: artist, song, url, blob, mime, thumbnail, thumbnailBlob,
isM3u (boolean, optional),
m3uResolvedEntries (array, optional)
- m3uResolvedEntries: for uploaded M3U, array of { artist, song, blob };
Blobs are stored so the M3U playlist works after refresh and when
switching tracks. Playlist creates blob URLs from these when applying.
2. 'state'
- Key: key (string)
- Fields: value (any)
- Keys: 'playlistOrder', 'lastTrackId', 'autoplayOnSelect'
Responsive Scaling
The player uses CSS transforms for responsive scaling:
function updatePlayerScale() {
var container = document.querySelector('.player');
var baseWidth = 982; // Design width
var scale = Math.min(
window.innerWidth / baseWidth,
window.innerHeight / baseWidth,
1.0 // Max scale
);
container.style.transform = 'scale(' + scale + ')';
}
๐จ Customization
Changing Colors
Edit CSS variables in style.css:
:root {
--accent: #FE4365; /* Change to your brand color */
--accent-rgb: 254, 67, 101; /* RGB values for rgba() */
--neutral: #F5F5F5; /* Neutral/background color */
}
Customizing Fonts
Replace font files in assets/fonts/ and update @font-face declarations.
Modifying Visualizer
Adjust visualizer parameters in player.js:
Framer.countTicks:Number of tick marks (default: 360)Framer.tickSize:Tick size multiplierTracker.barCount:Number of frequency barsScene.padding:Canvas padding
Adding Custom Presets
Add equalizer presets in player.js:
applyEqualizerPreset: function (preset) {
var presets = {
'flat': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
'bass': [6, 4, 2, 0, 0, 0, 0, 0, 0, 0],
'treble': [0, 0, 0, 0, 0, 2, 4, 6, 6, 6],
'vocal': [-2, -1, 2, 4, 3, 1, -1, -2, -2, -2],
'your-preset': [/* your values */]
};
// ... apply preset
}
๐ Browser Support
Supported Browsers
| Browser | Version | Notes |
|---|---|---|
| Chrome | 66+ | Full support |
| Firefox | 60+ | Full support |
| Safari | 11.1+ | Full support (iOS 11+) |
| Edge | 79+ | Full support |
| Opera | 53+ | Full support |
Required APIs
- HTML5 Audio: Core playback
- Web Audio API: Visualization and equalizer
- Canvas API: Visualizer rendering
- IndexedDB: Persistent storage (with localStorage fallback)
- CSS Variables: Theme system
- Fetch/XHR: Playlist loading
- File API: File uploads
- Blob URL: Local file playback
โก Performance
Optimization Techniques
1. Canvas Optimization
- Uses
requestAnimationFramefor smooth 60fps rendering - Efficient gradient caching
- Minimal redraws (only updates changed areas)
- High-DPI display support with proper scaling
2. Memory Management
- Automatic cleanup of blob URLs to prevent memory leaks
- Thumbnail blob URL management
- Efficient IndexedDB usage with proper transaction handling
3. Audio Processing
- Efficient Web Audio API graph (single chain)
- Minimal CPU usage for equalizer (BiquadFilterNode is hardware-accelerated)
- Optimized frequency analysis (only reads necessary data)
4. Code Optimization
- Vanilla JavaScript (no framework overhead)
- Minimal DOM manipulation
- Event delegation where possible
- Debounced resize handlers
Performance Metrics
| Metric | Value |
|---|---|
| Initial Load Time | < 500ms (without audio files) |
| Visualizer FPS | 60fps (target) |
| Memory Usage | < 50MB (typical) |
| CPU Usage | < 5% (idle), < 15% (playing) |
โฟ Accessibility
WCAG 2.1 AA Compliance
The application follows WCAG 2.1 Level AA guidelines:
Keyboard Navigation
| Key | Action |
|---|---|
Space |
Play/Pause |
โ |
Seek backward |
โ |
Seek forward |
โ |
Increase volume |
โ |
Decrease volume |
M |
Mute/Unmute |
S |
Toggle shuffle |
R |
Cycle repeat mode |
T |
Open/close speed panel |
Ctrl+F or / |
Focus playlist search (when playlist is open) |
Tab |
Navigate between controls |
Enter |
Activate focused control |
ARIA Labels
- All interactive elements have
aria-labelattributes - Buttons include descriptive labels
- Form inputs have associated labels
- Modal dialogs use
aria-modalandrole="dialog"
Screen Reader Support
- Semantic HTML5 elements
- Proper heading hierarchy
- Live regions for dynamic content updates
- Focus management for modals
Visual Accessibility
- High contrast color schemes
- Focus indicators on all interactive elements
- Sufficient touch target sizes (44x44px minimum)
- Scalable text and UI elements
๐ Code Quality Analysis
Code Structure
- Modular Design: Separated into logical modules (player, playlist, theme, storage)
- IIFE Pattern: All modules use Immediately Invoked Function Expressions to avoid global pollution
- Strict Mode: All files use
'use strict'for better error handling - Consistent Naming: Clear, descriptive variable and function names
Best Practices
- โ Error handling with try-catch blocks
- โ Defensive programming (null checks, type validation)
- โ Event listener cleanup
- โ Memory leak prevention (blob URL cleanup)
- โ Cross-browser compatibility
- โ Progressive enhancement
- โ Graceful degradation
Security Considerations
- Input sanitization for user-provided data
- Safe URL handling (no eval or innerHTML with user data)
- CORS-aware file loading
- XSS prevention through proper escaping
๐ Deployment
Local Development
- Clone or download the project
- Serve files via HTTP server (required for Web Audio API)
- Open
index.htmlin browser
index.html directly via file:// protocol will not work.
Production Deployment
- Upload all files to web server
- Ensure proper MIME types are configured
- Enable HTTPS for secure contexts (required for some APIs)
- Configure CORS headers if loading tracks from different domains
- Optimize audio files (consider compression)
Recommended Server Configuration
# Nginx example
location / {
try_files $uri $uri/ /index.html;
}
# MIME types
audio/mpeg mp3;
audio/ogg ogg;
audio/wav wav;
application/json json;
๐ Troubleshooting
Common Issues
Audio Not Playing
- Check browser console for CORS errors
- Ensure files are served over HTTP/HTTPS
- Verify audio file format is supported (MP3, OGG, WAV)
- Check browser autoplay policies
Visualizer Not Working
- Verify Web Audio API is supported
- Check browser console for errors
- Ensure audio is actually playing
IndexedDB Not Working
- Check browser support
- Verify storage permissions
- Check for quota exceeded errors
- Application will fallback to localStorage automatically
Drag-and-Drop Not Working
- Ensure IndexedDB is available (required for reordering)
- Check that tracks have valid IDs
- Verify touch/mouse events are not blocked
- Mobile: Ensure you drag far enough (threshold is 10px) before releasing
- Mobile: Try dragging to a position near the center of another track for better detection
- Check browser console for any IndexedDB errors
Picture-in-Picture Not Working
- Native PiP: Check if your browser supports Picture-in-Picture API (Chrome 70+, Edge 79+, Safari 13+)
- Native PiP: Ensure the page has user interaction before requesting PiP
- Custom Window: If native PiP fails, the custom floating window should appear automatically
- Buttons Not Clickable: Ensure the window is not behind other elements (check z-index)
- Position Not Saved: Check browser localStorage permissions
- Cross-Tab Support: Native PiP works across tabs; custom window works within the current tab only
- Check browser console for any errors related to PiP
๐ฎ Future Enhancements
Potential Features
- ๐ Playback statistics and analytics
- ๐ฑ Progressive Web App (PWA) support
- โ๏ธ Cloud storage integration
- ๐จ Custom visualizer themes
- ๐๏ธ Advanced recording features (pause/resume, multiple tracks)
- ๐ Internationalization (i18n)
- ๐ Advanced analytics and reporting
- ๐ก HLS/DASH streaming protocol support (via libraries)