Premise
It had to happen. Many of you will already know that Iām an audio and music buff (and for those who donāt know yet, look at my Znibbles YouTube channel, for example).
Weāll be looking at integrating an audio visualization library - Wavesurfer - with Stimulus by leveraging its internal event system and Stimulus values.
This touches upon many topics we have discussed before:
- Stimulus Value Callbacks
- Optimistic UI
- Integrating 3rd Party Libs
Have fun!
Starting Point
Markup
Letās look at the markup first. The whole affair is wrapped in a <div>
to which a peaks
Stimulus controller is attached:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=index.html%3AL42
Wavesurfer itself expects a container element and (optionally) an <audio>
element containing the source (I have used a small snippet of my own to avoid any copyright issues š
):
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=index.html%3AL43
Then, thereās a play button thatās already wired up to the playPause
action:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=index.html%3AL53
And an <input>
field to add descriptions for markers:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=index.html%3AL63
The respective button is connected to the addMarkerAtCurrentTime
action. Last but not least, thereās a list
target to hold textual descriptions of the markers:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=index.html%3AL78
JavaScript
The PeaksController
already has the Wavesurfer boilerplate configured for you:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=controllers%2Fpeaks_controller.js%3AL22
Thatās also the case for the Regions
plugin, which is required to store and manipulate markers (which are simply regions without an end timestamp):
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=controllers%2Fpeaks_controller.js%3AL34
The logic to handle the addition of regions to a Wavesurfer instance is also provided:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=controllers%2Fpeaks_controller.js%3AL66
Challenge
To warm up, letās look at what has to happen when the play/pause button is pressed. Wavesurfer triggers an internal event (example here), which you should listen for and update the playing
value accordingly. Note that the playingValueChanged
listener to update the button label is already in place.
Add your event handling logic here: https://stackblitz.com/edit/stimulus-wavesurfer-1?file=controllers%2Fpeaks_controller.js%3AL36
Next, letās implement adding a marker. Weāll do this by adding an item to the markers
value and handle the respective callback accordingly. First, when the āAdd Markerā button is pressed, youāll have to add a new item to this.markersValue
and clear the input field:
https://stackblitz.com/edit/stimulus-wavesurfer-1?file=controllers%2Fpeaks_controller.js%3AL63
Then, you need to compare the new and old values in the callback to filter out the additions, and call #handleAddition
on each:
Finally, we also want to add items to the listTarget
so we have a rundown of all the markers. My recommendation would be to again utilize the regions pluginās event system, i.e. the region-created
event to add such an item. Hint: Use this.regions.on('...')
.
Below is a rendering of the result:
Teasers
- How - and where in the client side logic - would you trigger persisting the markers?
- Letās say another user can add markers too, and these are morphed into the
data-peaks-markers
attribute. Is your code ready to display those too?