Web Player
A high-fidelity, glassmorphic companion interface designed for seamless synchronization across Telegram MiniApp and desktop browsers. Built with Next.js 16 and the Web Audio API.
Multi-Platform Architecture
Telegram MiniApp
Compressed, performance-optimized version that lives directly inside chat threads. Uses Telegram's WebApp SDK for theme synchronization and haptic feedback.
- • Automatic theme adaptation (light/dark)
- • Native back button integration
- • Viewport expansion for immersive mode
Desktop Browser
Full-screen visualizer mode with high-bitrate audio processing and multi-room management. Supports Wake Lock API to prevent screen dimming during playback.
- • Canvas-based frequency visualizer
- • Picture-in-Picture support
- • Keyboard shortcuts (Space, Arrow keys)
Drift-Corrected Playback
NTP-style clock synchronization for sub-100ms accuracy.
The player uses a server-time offset calculation to adjust local playback. Every 5 seconds, it compares the local clock against the backend's authoritative timestamp.
Sync Algorithm
- 1. Receive
stateUpdatewithsongStartedAttimestamp - 2. Calculate
expectedTime = (Date.now() - songStartedAt) / 1000 - 3. Compare with
audioElement.currentTime - 4. If drift > 0.5s, seek to
expectedTime
// Drift correction logic
const drift = Math.abs(
audio.currentTime - expectedTime
);
if (drift > 0.5) {
audio.currentTime = expectedTime;
console.log('Corrected drift:', drift);
}Core Technologies
Canvas Visualizer
Real-time frequency analysis using the Web Audio API. The player creates an AnalyserNode connected to the audio source, extracting FFT data at 60fps and mapping it to dynamic SVG paths for premium aesthetic feedback.
const audioContext = new AudioContext();
const analyser = audioContext.createAnalyser();
analyser.fftSize = 256;
const source = audioContext.createMediaElementSource(audioElement);
source.connect(analyser);
analyser.connect(audioContext.destination);Wake Lock Integration
Prevents screen dimming during active playback using the Screen Wake Lock API. The lock is automatically released when the user pauses or switches tabs, conserving battery life.
Dynamic Theming
Automatically extracts dominant colors from album artwork using canvas pixel sampling. The extracted palette is applied to gradients, glows, and glassmorphic overlays for a cohesive visual experience.
State Management Architecture
The frontend uses React hooks and Socket.IO for real-time state synchronization.
| State Hook | Purpose | Update Trigger |
|---|---|---|
| currentSong | Active track metadata (title, artist, thumbnail) | Socket: stateUpdate |
| queue | Upcoming songs array | Socket: queueUpdated |
| viewers | Active user presence list | Socket: viewersUpdated |
| playing | Boolean playback state | Socket: stateUpdate |
Performance Optimizations
Image Lazy Loading
Album artwork is loaded with loading="lazy" and low-quality placeholders (LQIP) to reduce initial bundle size.
Code Splitting
Heavy components like the Lyrics panel and Debug view are dynamically imported using React.lazy().
Debounced Seek
Seek operations are debounced by 300ms to prevent excessive Socket.IO emissions during slider dragging.
Memoized Renders
Queue and viewer lists use React.memo() to prevent unnecessary re-renders on state updates.
Deployment Tip
For production deployments, ensure NEXT_PUBLIC_API_URL points to your backend's public URL. The player will automatically establish a Socket.IO connection on mount. Use Vercel or Netlify for zero-config deployments with automatic HTTPS.