<.wavesurfer>: an audio waveform (WaveSurfer.js), through Xenia's official adapter.
Setup
Install the library in your app:
npm install wavesurfer.js --prefix assetsPass it to the adapter, and register it, in assets/js/app.js:
import { createWaveSurfer } from "xenia/wavesurfer"
const wavesurfer = createWaveSurfer({
load: async () => {
const [ws, regions, timeline, minimap, hover, spectrogram] = await Promise.all([
import("wavesurfer.js"),
import("wavesurfer.js/dist/plugins/regions.esm.js"),
import("wavesurfer.js/dist/plugins/timeline.esm.js"),
import("wavesurfer.js/dist/plugins/minimap.esm.js"),
import("wavesurfer.js/dist/plugins/hover.esm.js"),
import("wavesurfer.js/dist/plugins/spectrogram.esm.js"),
])
return {
WaveSurfer: ws.default,
RegionsPlugin: regions.default,
TimelinePlugin: timeline.default,
MinimapPlugin: minimap.default,
HoverPlugin: hover.default,
SpectrogramPlugin: spectrogram.default,
}
},
})
hooks: { ...colocatedHooks, ...createHooks({ WaveSurfer: wavesurfer }) },Then import Xenia.Adapters.WaveSurfer in html_helpers, and render
<.wavesurfer id="..."> with the props below. Every event becomes an
on_<event> attribute; commands go through Xenia.push_to/4.
The factory returns a plain adapter object: spread it to add or change props, commands and events, without copying the adapter.
The tag uses the adapter name "WaveSurfer". To register it under
another name, render <.xenia adapter="..."> or declare your own tag.
Reference
Xenia's official adapter for WaveSurfer.js (v7/v8): one audio file as an interactive waveform, with regions, markers, timeline, minimap, hover and spectrogram. For several synchronized tracks and recording, see wavesurfer_multitrack.js.
Props:
url audio URL. Changing it loads the new file.
peaks precomputed peaks (list of channels) for instant drawing of
long files; needs `duration` too
duration seconds, with `peaks`
options any WaveSurfer option, camelCase or snake_case, applied in
place: wave_color, progress_color, cursor_color, height,
bar_width, bar_gap, bar_radius, normalize, split_channels,
drag_to_seek, auto_scroll, auto_center, ...
zoom pixels per second (0 = fit the container)
volume 0..1
muted boolean
playback_rate 0.25..4 (pitch preserved)
regions [%{id, start, end?, color?, content?, drag?, resize?}]
The server owns the list: regions are added, updated and
removed to match it. A region without `end` is a marker.
region_editing true lets the user drag on the waveform to create
regions (sent as region_created; add them to `regions`)
timeline true or %{height, time_interval, primary_label_interval, ...}
minimap true or %{height, wave_color, ...}
hover true or %{line_color, label_color, ...}
spectrogram true or %{height, fft_samples, frequency_min, frequency_max,
labels, scale, color_map, ...}
Plugin props: false or nil removes the plugin; a changed map rebuilds it.Commands:
play %{start?, end?}, pause, play_pause, stop
seek %{seconds}, skip %{seconds}
play_region %{id}
download_image %{filename?} the waveform as PNGEvents:
ready %{duration}
loading %{percent} at most every 250 ms
playback %{state: "playing" | "paused", seconds}
position %{seconds} while playing, at most every 250 ms
seek %{seconds} the user clicked or dragged
finish %{}
zoom %{px_per_sec} at most every 250 ms
region_created %{region} the user drew a region
region_updated %{region} the user moved/resized one
region_clicked %{region}
region_in, region_out %{region} playback entered/left a region
error %{source, message, code}
`region` is %{id, start, end, color, content}.
Summary
Functions
Attributes
id(:string) (required) - Stable DOM id used for adapter commands.url(:string)peaks(:list)duration(:any)options(:map)zoom(:any)volume(:any)muted(:boolean)playback_rate(:any)regions(:list)region_editing(:boolean)timeline(:any)minimap(:any)hover(:any)spectrogram(:any)on_ready(:string) - LiveView event triggered when the adapter emits :ready. Defaults tonil.on_loading(:string) - LiveView event triggered when the adapter emits :loading. Defaults tonil.on_playback(:string) - LiveView event triggered when the adapter emits :playback. Defaults tonil.on_position(:string) - LiveView event triggered when the adapter emits :position. Defaults tonil.on_seek(:string) - LiveView event triggered when the adapter emits :seek. Defaults tonil.on_finish(:string) - LiveView event triggered when the adapter emits :finish. Defaults tonil.on_zoom(:string) - LiveView event triggered when the adapter emits :zoom. Defaults tonil.on_region_created(:string) - LiveView event triggered when the adapter emits :region_created. Defaults tonil.on_region_updated(:string) - LiveView event triggered when the adapter emits :region_updated. Defaults tonil.on_region_clicked(:string) - LiveView event triggered when the adapter emits :region_clicked. Defaults tonil.on_region_in(:string) - LiveView event triggered when the adapter emits :region_in. Defaults tonil.on_region_out(:string) - LiveView event triggered when the adapter emits :region_out. Defaults tonil.on_error(:string) - LiveView event triggered when the adapter emits :error. Defaults tonil.shortcuts(:map) - Key combination => LiveView event, while focus is inside (see Xenia.Shortcuts). Defaults to%{}.on_crash(:string) - LiveView event sent if the adapter throws (see Xenia.Component). Defaults tonil.- Global attributes are accepted.
Slots
loading- Shown until the island's first mount finishes.error- Shown if the adapter throws; data-xenia-retry starts it again.