WaveformPlayer options
Every forwarded option lives in the core player options reference.
Construct with a selector or element and optional options:
const playlist = new WaveformPlaylist('#my-playlist', { layout: 'list', // or 'minimal' | 'hero' | 'grid' continuous: true, waveformStyle: 'mirror', // any core player option passes through height: 80});The constructor resolves the container, verifies window.WaveformPlayer, parses options and tracks, and — if any [data-track] was found — auto-initialises. It throws [WaveformPlaylist] Container element not found for a missing selector/element. With zero parsed tracks it constructs but does nothing further.
| Method | Description |
|---|---|
selectTrack(index: number): void |
Load track index into the player via loadTrack(...); updates the active-row UI, resets currentChapterIndex to -1 (clearing any chapter highlight), and reveals that track’s nested .wp-chapters block. No-op if out of range. |
seekToChapter(trackIndex: number, time: number): void |
Same track: seekTo(time) (and play() if paused). Cross-track: selects trackIndex and seeks once that track’s onLoad fires. No-op if trackIndex is out of range. |
nextTrack(): void |
selectTrack(currentTrackIndex + 1) when not already on the last track. |
previousTrack(): void |
selectTrack(currentTrackIndex - 1) when not already on the first track. |
getPlayer(): WaveformPlayer | null |
The underlying player instance (null before init / after destroy()). |
getCurrentTrackIndex(): number |
Zero-based index of the selected track. |
getTracks(): WaveformPlaylistTrack[] |
The parsed track objects (element, index, url, title, artist, artwork, album, duration, waveform, chapters[], markers[]). Chapters are sorted by time. |
destroy(): void |
Removes the keydown listener, cancels any pending chapter seek, destroys the player, removes only the nodes and layout classes the playlist added (your own classes stay), un-hides the [data-track] elements in place, clears data-waveform-playlist-initialized, and nulls player / listElement / tracks. The container can then be initialised again. |
WaveformPlaylist.init() (static) |
Auto-initialise every [data-waveform-playlist] not already marked initialised. Per-element errors are caught and console.error’d. |
playlist.nextTrack();playlist.seekToChapter(0, 330); // jump to 5:30 on track 0const current = playlist.getCurrentTrackIndex();The instance exposes (typed in index.d.ts): container, options, tracks[], currentTrackIndex, currentChapterIndex, player, and isPlaying.
A single, focus-scoped document keydown listener handles navigation. It only acts when this playlist’s container or its inner player holds focus, so multiple playlists on a page never cross-fire.
| Key | Action | Condition |
|---|---|---|
N |
Next track | More than one track, and the playlist or its player has focus. |
P |
Previous track | More than one track, and the playlist or its player has focus. |
1–9 |
Select track by number | More than one track, and a playlist row (not the player) has focus. |
Keys pressed with Ctrl, Cmd or Alt held pass through untouched (1.8.0+), so browser shortcuts like Cmd/Ctrl+P (print) and Ctrl/Alt+digit (switch tab) keep working. Shift is allowed.
Track rows (.wp-item), chapter rows (.wp-chapter, .wp-chapter-item) and minimal buttons (.wp-track-btn) are all keyboard-operable: rows expose role="button", join the tab order, and activate on click, Enter, or Space.
The playlist dispatches no custom DOM events of its own — it has no emit path. Instead it drives itself off the core player’s callbacks. Any of these you pass as options still run, after the playlist’s handling (1.8.0+):
| Source | Effect |
|---|---|
player onEnd |
Resets chapter highlight to the start; auto-advances to the next track if continuous and not on the last track. |
player onTimeUpdate(current, total) |
Re-highlights the active chapter row (.wp-active + aria-current; chapters sharing a start time highlight the first), updates the hero/grid time readout, and — once the duration is known — warns about chapters that start after the track ends. |
player onPlay |
Sets isPlaying = true, marks the active track, updates the artwork overlay icon to ti-player-pause. |
player onPause |
Sets isPlaying = false, updates the overlay icon to ti-player-play; if paused at the end (current >= duration - 0.1) resets currentChapterIndex = -1 and re-highlights chapter 0. |
player onLoad(player) |
Runs a pending cross-track chapter seek if this is the track it was waiting for. |
player onError |
Cancels a pending chapter seek. |
player onNextTrack / onPreviousTrack |
The lock-screen / Media Session skip buttons call nextTrack() / previousTrack(). |
To listen for player-level events (play, pause, seek, ended, etc.), attach to the player instance returned by getPlayer() — see the player events reference.
The playlist generates a structured DOM you can target for theming. Key hooks:
| Class | Element |
|---|---|
.waveform-playlist |
The container (base styles), added on init. Layout modifiers: .wp-minimal, .wp-hero-layout, .wp-grid-layout, plus .wp-density-compact (density: 'compact'), .wp-cover-top (coverPosition: 'top') and .wp-no-artist (showArtist: false). |
.wp-player |
The generated player wrapper (list / minimal layouts). In the hero and grid layouts the embedded player renders into .wp-hero-stage instead. |
.wp-list-container / .wp-list |
The list wrapper and the <ul> track list. .wp-chapters-only is the single-track-with-chapters variant. |
.wp-item |
Track row (role="button"). .wp-active marks the active row. |
.wp-indicator |
Track-number badge (shown when a track has no artwork). |
.wp-artwork-container / .wp-artwork / .wp-artwork-overlay |
Artwork wrapper, image, and the active-track play/pause overlay. |
.wp-info / .wp-title / .wp-artist / .wp-duration |
The text column. |
.wp-chapters / .wp-chapter |
Nested chapter list and rows under a track (multi-track). .wp-chapter-time / .wp-chapter-label for the row contents. |
.wp-chapter-item / .wp-time / .wp-label |
Rows in the single-track chapters-only list. |
.wp-controls / .wp-track-btn |
Minimal-layout button container and buttons (aria-pressed reflects selection). |
.wp-hero / .wp-hero-cover / .wp-hero-art / .wp-hero-overlay |
Hero — the “now playing” unit, the cover play/pause button, its image, and the overlay icon. |
.wp-hero-stage / .wp-hero-meta / .wp-hero-title / .wp-hero-sub / .wp-hero-time |
Hero — the waveform stage (hosts the player) and the title / artist / current-total-time meta row. |
.wp-queue / .wp-queue-item / .wp-queue-thumb / .wp-queue-state |
Hero — the stripped track queue: list, row, thumbnail, and the per-row play-state indicator. |
.wp-now-bar / .wp-now-bar-top / .wp-now-meta |
Grid — the slim now-playing transport bar (.wp-now-bar-top when barPosition: 'top') and its title/time meta. |
.wp-grid / .wp-grid-item / .wp-grid-cover / .wp-grid-art / .wp-grid-title |
Grid — the card container, a card (active card is ringed), the cover wrapper, image, and title. |
Call destroy() when removing a playlist (e.g. in a SPA route change). It removes the keydown listener, destroys the inner player, removes the generated UI, and leaves your original [data-track] markup in place — so the same container can be initialised again with new WaveformPlaylist(el, …) or WaveformPlaylist.init(). (Before 1.8.0 it wiped the container first, so the tracks were lost and the React/Vue/Svelte wrappers rebuilt an empty playlist on a prop change.)
playlist.destroy();WaveformPlayer options
Every forwarded option lives in the core player options reference.
Installation
Full setup for the waveform family — see getting started.