jukette
v0.3.0
Published
White-label jukebox custom element for audio, SoundCloud, and MIDI playlists.
Downloads
277
Maintainers
Readme
jukette
A white-label jukebox custom element exposed as <jukette-player>.
Jukette v0.3.0
By Rémino Rem
https://remino.net/
Docs | Code Repo | npm Package
Installation
HTML (CDN)
Register the custom element automatically from a CDN:
<script src="https://unpkg.com/jukette"></script>Mirrors:
- https://unpkg.com/jukette
- https://cdn.jsdelivr.net/npm/jukette
Use a pinned version in production:
<script src="https://unpkg.com/[email protected]"></script>If you want the API instead of auto-registration, import the ES module directly:
<script type="module">
import { defineJuketteElement } from 'https://unpkg.com/[email protected]/dist/jukette.mjs'
defineJuketteElement()
</script>npm
Install the package first:
npm install juketteThen register the custom element automatically:
import 'jukette/auto'Or import the explicit API:
import { defineJuketteElement } from 'jukette'
defineJuketteElement()TypeScript declarations are included with the package.
Direct download
Download the package tarball or individual files from npm/CDN:
- https://www.npmjs.com/package/jukette
- https://unpkg.com/jukette/dist/
- https://cdn.jsdelivr.net/npm/jukette/dist/
The browser-ready auto-registration file is dist/jukette-auto.min.js.
Distribution files:
dist/jukette.mjs: ES module library API.dist/jukette.cjs: CommonJS library API.dist/jukette-auto.mjs: ES module auto-registration entry.dist/jukette-auto.cjs: CommonJS auto-registration entry.dist/jukette-auto.min.js: minified classic browser auto-registration.
Usage
After registration, use the element with a single source:
<jukette-player src="/audio/theme.mp3"></jukette-player>Or pass a playlist with child track elements:
<jukette-player preload-metadata prefer-media-metadata>
<jukette-track
title="Theme"
artist="Local"
src="/audio/theme.mp3"
></jukette-track>
<jukette-track
title="Sketch"
src="/midi/sketch.mid"
type="midi"
></jukette-track>
<jukette-track
title="Set"
src="https://soundcloud.com/example/set"
></jukette-track>
</jukette-player>Playlist
Use direct <jukette-track> children for authored HTML. Browser HTML requires
explicit closing tags, so write <jukette-track></jukette-track> rather than a
self-closing tag.
For generated markup or compatibility with older usage, the playlist
attribute also accepts JSON. Each item can be either a URL string or a track
object.
[
"/audio/one.mp3",
{
"title": "Two",
"artist": "Example",
"src": "/audio/two.ogg",
"type": "audio",
"preferMediaMetadata": false
}
]When JSON parsing fails, Jukette treats the attribute as a newline-separated URL list.
Track sources are resolved in this order:
player.playlistset from JavaScript.- Direct
<jukette-track>children. playlistattribute JSON or newline list.- Single
srcattribute.
Tracks
<jukette-track> attributes and track object fields:
src: required URL for a local audio file, local MIDI file, or SoundCloud URL.title: optional display title.artist: optional display artist.type: optionalaudio,midi, orsoundcloud.prefer-media-metadata/preferMediaMetadata: optional per-track override for the player's media metadata preference.
If type is omitted, Jukette infers SoundCloud URLs and .mid / .midi files.
Everything else is treated as browser-native audio.
MIDI playback uses a small built-in Standard MIDI File parser and Web Audio synth. It is intentionally simple and suitable for local MIDI previews, not a full General MIDI instrument set.
API
Each element exposes:
const player = document.querySelector('jukette-player')
player.play()
player.pause()
player.toggle()
player.next()
player.previous()
player.seek(30)
player.currentTime = 30
console.log(player.currentTime)
console.log(player.currentTrack)
console.log(player.currentTrackIndex)
console.log(player.totalTracks)
player.playlist = [{ title: 'Track', src: '/track.mp3' }]
player.playlistOpen = true
player.preloadMetadata = true
player.preferMediaMetadata = true
player.midiOscillator = 'sine'Use the preload-metadata attribute or preloadMetadata property to discover
playlist durations before tracks are played. Jukette preloads metadata for
browser-native audio and local MIDI tracks. SoundCloud durations are reported
when the SoundCloud widget has loaded that track.
Use currentTime to read the current playback position in seconds. Assigning
to currentTime seeks, matching native media element behavior.
Use currentTrack, currentTrackIndex, and totalTracks to inspect playlist
state. Use playlistOpen to read or set whether the playlist panel is expanded.
Use prefer-media-metadata or preferMediaMetadata to let readable media-file
tags override authored track titles and artists. Jukette currently reads MP3
ID3 TIT2 title and TPE1 artist tags, plus MIDI track/sequence names as
titles. SoundCloud display metadata is loaded from oEmbed when available. MIDI
artists stay authored-only. Authored values stay in place when tags are missing,
unreadable, or unsupported.
Direct <jukette-track> children and JavaScript track objects can override the
player-level preference per track. Use prefer-media-metadata or
preferMediaMetadata: true to force metadata display for that track, use
prefer-media-metadata="false" or preferMediaMetadata: false to force
authored display values, or omit it to inherit the player setting.
Use midi-oscillator or midiOscillator to choose the built-in MIDI preview
oscillator. Supported values are auto, sine, square, sawtooth, and
triangle. auto is the default and maps MIDI program changes to a simple
preview timbre; invalid values fall back to auto.
Jukette dispatches bubbling composed custom events from the <jukette-player>
host:
jukette:playjukette:pausejukette:nextjukette:previousjukette:restartjukette:seekjukette:endedjukette:trackchangejukette:volumechangejukette:playlisttoggle
Each event includes event.detail with the current track, tracks, index,
type, currentTime, duration, volume, playing, and playlistOpen.
Navigation events also include fromIndex, toIndex, and direction; playlist
toggle events include open.
Styling
Jukette keeps the default UI basic on purpose. It uses inherited text color and font, a single border, and native range controls. Style the host element first:
jukette-player {
color: #111;
font:
1rem/1.4 system-ui,
sans-serif;
max-inline-size: 36rem;
--jukette-control-size: 2.25rem;
}The host supports these stable styling inputs:
color: inherited by text, borders, buttons, and range accents.font: inherited by labels, buttons, and playlist items.--jukette-control-size: controls the square previous, play, next, and playlist-toggle button size. Defaults to2em.inline-size,max-inline-size,margin, and other normal layout properties onjukette-player.
Use host attributes for state-specific styling:
jukette-player[playlist-open] {
border-color: currentColor;
}
jukette-player[data-kind='soundcloud'] {
color: #f50;
}
jukette-player[data-kind='midi'] {
color: #164e63;
}Range inputs use accent-color: currentColor inside the shadow DOM, so changing
the host color changes the seek and volume accents in browsers that support
native range accent styling.
For deeper styling, Jukette exposes stable ::part() hooks:
- Layout:
player,track,progress,seek,time,controls,playlist. - Track display:
title,artist,status. - Time display:
elapsed,remaining,total. - Controls:
button,previous-button,play-button,next-button,playlist-button,seek-input,volume. - Playlist rows:
playlist-item,playlist-track,playlist-title,playlist-artist,playlist-duration. - SoundCloud iframe:
soundcloud.
jukette-player::part(player) {
border: 0;
padding: 0;
}
jukette-player::part(play-button) {
border-radius: 999px;
}
jukette-player::part(playlist-track) {
padding-block: 0.5rem;
}Development
npm install
npm run dev
npm run buildThe library source lives in src/lib. The documentation site is built with
Astro and lives in the rest of src.
Release
Release automation is available through release-it. A release runs checks,
builds, publishes the npm package, pushes the release commit and tag, creates a
GitHub release, uploads dist/*, then publishes docs:
npm run release:dry-run
npm run releaseIf docs publishing fails after the package release, rerun it directly:
npm run docs:publishBefore running a real release, make sure RELEASE_IT_GITHUB_TOKEN is set and
npm whoami --registry https://registry.npmjs.org/ passes. Release-it prompts
for an npm OTP when npm requires one.
Contributing
- Fork the repository.
- Create a feature branch:
git checkout -b feature/amazing-feature. - Make your changes.
- Run
npm run buildandnpm test. - Commit, push, and open a pull request.
Licence
ISC. See LICENSE.md.
