Skip to main content

Overview

The LyricsManager class handles synchronized lyrics display over the cover art with timestamp-based synchronization. It supports both real-time audio playback and virtual time-based synchronization for streaming scenarios.

Features

  • Adaptive streaming delay for iOS/Safari and Desktop/Android devices
  • Virtual time synchronization for live streams
  • LRC format parsing support
  • Automatic visibility handling on tab changes
  • Smooth fade animations

Constructor

const lyricsManager = new LyricsManager();
Creates a new LyricsManager instance and initializes DOM references and event listeners.

Properties

lyrics
Array
default:"[]"
Array of lyric objects with time and text properties, sorted by time
currentIndex
Number
default:"-1"
Index of the currently displayed lyric line
audioElement
HTMLAudioElement
default:"null"
Reference to the audio element for real-time synchronization
isActive
Boolean
default:"false"
Whether the lyrics system is currently active
timeOffset
Number
default:"0"
Initial time offset in seconds for the song (elapsed time when loaded)
useVirtualTime
Boolean
default:"false"
Whether to use virtual time based on Azura timestamp instead of audio element time
customDelay
Number|null
default:"null"
Custom delay in seconds (null = use LYRICS_CONFIG.STREAM_DELAY)

Methods

init()

Initializes the lyrics manager with an audio element reference.
lyricsManager.init(audioElement);
audioElement
HTMLAudioElement
required
The HTML5 audio element to synchronize with
Example:
const audio = document.getElementById('audioPlayer');
lyricsManager.init(audio);

loadLyrics()

Loads lyrics from an array and starts synchronization.
lyricsManager.loadLyrics(lyricsData, startOffset, customDelay);
lyricsData
Array
required
Array of objects with format: [{time: seconds, text: "lyric text"}]
startOffset
Number
default:"0"
Initial elapsed time in seconds (used for live streams)
customDelay
Number|null
default:"null"
Custom delay in seconds to compensate for stream latency (null = use default adaptive delay)
Example:
const lyrics = [
  { time: 0.5, text: "First line of lyrics" },
  { time: 3.5, text: "Second line appears here" },
  { time: 6.5, text: "Third line continues" }
];

// Basic usage
lyricsManager.loadLyrics(lyrics);

// With stream offset and custom delay
lyricsManager.loadLyrics(lyrics, 45.2, 2.0);
Behavior:
  • Automatically sorts lyrics by timestamp
  • Shows the overlay if lyrics are present
  • Enables virtual time mode if startOffset > 0
  • Starts update interval for virtual time synchronization

loadFromLRC()

Parses and loads lyrics from LRC format text.
lyricsManager.loadFromLRC(lrcText);
lrcText
String
required
Lyrics in LRC format with timestamps like [mm:ss.xx] or [mm:ss]
Example:
const lrcContent = `
[00:12.00]Line one
[00:17.50]Line two
[00:23.00]Line three
`;

lyricsManager.loadFromLRC(lrcContent);
Supported formats:
  • [mm:ss] - Minutes and seconds
  • [mm:ss.xx] - Minutes, seconds, and centiseconds
  • [mm:ss.xxx] - Minutes, seconds, and milliseconds

getCurrentTime()

Calculates the current playback time, accounting for virtual time or audio element time.
const currentTime = lyricsManager.getCurrentTime();
Returns: Number - Current time in seconds Behavior:
  • In virtual time mode: Returns timeOffset + elapsed - streamDelay
  • In audio mode: Returns audioElement.currentTime
  • Uses customDelay if set, otherwise uses LYRICS_CONFIG.STREAM_DELAY

updateLyrics()

Updates the displayed lyrics based on current playback time.
lyricsManager.updateLyrics();
Called automatically by:
  • Audio timeupdate event (non-virtual mode)
  • Update interval (virtual mode, every 100ms)
Behavior:
  • Finds the appropriate lyric line for current time
  • Updates display only when line changes
  • Calls displayLyric() with new index

displayLyric()

Displays the lyric at the specified index with animation.
lyricsManager.displayLyric(index);
index
Number
required
Index of the lyric line to display
Behavior:
  • Updates current lyric with fade-in animation
  • Shows previous lyric with reduced opacity
  • Logs displayed lyric in development mode

show()

Shows the lyrics overlay with smooth fade-in animation.
lyricsManager.show();
Behavior:
  • Sets display to flex
  • Adds active class after 50ms for CSS transition
  • Sets isActive to true

hide()

Hides the lyrics overlay with smooth fade-out animation.
lyricsManager.hide();
Behavior:
  • Removes active class for fade-out
  • Sets display to none after 1200ms (transition duration)
  • Only deactivates if no lyrics are loaded

clear()

Clears current lyrics and resets state.
lyricsManager.clear(keepActive);
keepActive
Boolean
default:"true"
If true, keeps the system active for quick reload; if false, fully deactivates
Example:
// Clear but keep system ready
lyricsManager.clear();

// Full deactivation
lyricsManager.clear(false);
Behavior:
  • Clears lyrics array and resets indices
  • Stops virtual time updates
  • Removes custom delay setting
  • Optionally hides overlay completely

startVirtualTimeUpdate()

Starts the interval-based update loop for virtual time mode.
lyricsManager.startVirtualTimeUpdate();
Behavior:
  • Clears any existing interval
  • Creates new interval at LYRICS_CONFIG.UPDATE_INTERVAL (100ms)
  • Updates only when active, has lyrics, in virtual mode, and tab is visible

stopVirtualTimeUpdate()

Stops the virtual time update interval.
lyricsManager.stopVirtualTimeUpdate();

Static Methods

getDemoLyrics()

Returns sample lyrics for testing and demonstration.
const demoLyrics = LyricsManager.getDemoLyrics();
Returns: Array - Array of 10 sample lyric objects Example:
const demo = LyricsManager.getDemoLyrics();
lyricsManager.loadLyrics(demo);

Configuration

The module uses an adaptive configuration based on device detection:
const LYRICS_CONFIG = {
  STREAM_DELAY: isIOS ? 4.5 : 1.5, // Seconds
  UPDATE_INTERVAL: 100 // Milliseconds
};
  • iOS (iPhone/iPad): 4.5 seconds delay due to Safari’s aggressive buffering
  • Desktop/Android: 1.5 seconds delay for standard streaming latency
  • Custom Delay: Can be overridden using the customDelay parameter in loadLyrics()

Usage Example

// Initialize
const lyricsManager = new LyricsManager();
const audio = document.getElementById('audioPlayer');
lyricsManager.init(audio);

// Load lyrics
const lyrics = [
  { time: 0.5, text: "First line" },
  { time: 3.5, text: "Second line" },
  { time: 6.5, text: "Third line" }
];

lyricsManager.loadLyrics(lyrics);

DOM Requirements

The LyricsManager expects these elements in the DOM:
  • #lyricsOverlay - Main overlay container
  • #lyricsBackdrop - Backdrop element for visual effects
  • #lyricsPrevious - Container for previous lyric line
  • #lyricsCurrent - Container for current lyric line

Event Handling

When the tab becomes visible again after being hidden:
  • Reconnects the lyrics system
  • Restarts virtual time updates if needed
  • Updates lyrics to current position
  • Shows the overlay if lyrics exist

Build docs developers (and LLMs) love