The Bespoken Audio player is a web component that makes embedding audio on a website easier. This page contains working examples on how it can be used. Find the project on NPM and GitHub.
Let's look at a basic usage first. The tracks
attribute is required. The value must be formatted
as a valid Javascript array of objects defining each track. Each track must have a src
. The tracks
create a playlist inside the player.
<bespoken-audio-player tracks='[{"src": "track-1.mp3"}]'></bespoken-audio-player>
Each track
may have a title
as shown in the next example. This title is only useful
to the end user if the title is shown. We can display the playlist by including the
playlist-visible
<bespoken-audio-player playlist-visible tracks='[{"src": "track-1.mp3", "title": "Track One: Introducing the Bespoken Audio Player"}]'></bespoken-audio-player>
Unlike the native audio tag in HTML, the Bespoken Audio Player accept multiple tracks. When the playlist has
more than one track, a previous and next buttons are added to the player. This example also demonstrates what
happens if you leave out the title
in one of the tracks. Notice that track-2
is
displayed in the second spot in the playlist, which is the filename without the extension.
<bespoken-audio-player
playlist-visible
tracks='[{"src": "track-1.mp3", "title": "Track One: Introducing the Bespoken Audio Player"},
{"src": "track-2.mp3"},
{"src": "track-3.mp3", "title": "Track Three"}]'
></bespoken-audio-player>
If you only want to display the currently playing track, you can use the
only-current-track-visible
attribute.
<bespoken-audio-player
only-current-track-visible
tracks='[{"src": "track-1.mp3", "title": "Track One: Introducing the Bespoken Audio Player"},
{"src": "track-2.mp3", "title": "Track Two"},
{"src": "track-3.mp3", "title": "Track Three"}]'
></bespoken-audio-player>
slots
to change the buttons and looping content.There are slots
for the control buttons, play-icon
, pause-icon
, prev-icon
,
next-icon
. You can insert new icon images or text. In the following example, it simply uses text.
This example also shows that you can also have the playlist loop back through the playlist by adding the loop
attribute
<bespoken-audio-player playlist-visible loop tracks='[{"src": "track-1.mp3", "title": "Track One: Introducing the Bespoken Audio Player"}, {"src": "track-2.mp3", "title": "Track Two"}, {"src": "track-3.mp3", "title": "Track Three"}]' > <span slot="play-icon">Play</span> <span slot="pause-icon">Stop</span> <span slot="prev-icon">Prev</span> <span slot="next-icon">Next</span> </bespoken-audio-player>
The Bespoken Audio Player emits 5 custom events. Since the player is written in TypeScript, each event is typed to help with code completion.
play: TrackPlayEvent
- when a track starts playing
pause: TrackPauseEvent
- when a track is paused
ended: TrackEndedEvent
- when a track ends
trackChange: TrackErrorEvent
- when the track changes
error: TrackChangeEvent
- when there is an error loading a track
If there is an error in retrieving a track, when the play head gets to that track, it will be skipped over in
the playlist. Take note of the missing-track.mp3
in the playlist code. This is an intentional error
used to demonstrate how errors are handled with the player.
If you are writing plain Javascript, you would do something like the following example.
<bespoken-audio-player id="event-example" playlist-visible tracks='[{"src": "track-1.mp3", "title": "Track One: Introducing the Bespoken Audio Player"}, {"src": "missing-track.mp3", "title": "This track is missing from the filesystem"}, {"src": "track-3.mp3", "title": "Track Three"}]' > </bespoken-audio-player> <script> const player = document.getElementById('event-example'); if (!player) { player.addEventListener('play', (e) => { if (e instanceof CustomEvent && e.detail) { const {trackIndex, track} = e.detail; console.log(`Custom Bespoken Audio Event: play, track ${trackIndex}: ${track.title}`, e.detail); } }); } </script>
This demo page is written in Typescript, which looks more like the following snippet:
player?.addEventListener('play', (e: TrackPlayEvent) => { const { trackIndex, track } = e.detail; console.log(`Custom Event: bespoken-play, track ${trackIndex}: ${track.title}`); sendNotification({ title: `Play event - track ${trackIndex}: ${track.title}`, }); });
The sendNotification
is a function that is not part of Bespoken Audio Player. I use it to provide
visual feedback on this page of when events are fired. In production, you'd probably include a call to your
analytics or bug catching service at this point instead. You'll notice the playlist numbering starts at 0, not
1.
The web component exposes numerous :parts
and styling variables. One particular customization is
grouping the previous and next buttons together. Below is an example of how to do that. Notice that this example
also includes some
Tailwind CSS classes directly on
the web component to give it a border and a green background.
This player also demonstrates how titles that are too long to display on a single line, in track 2, are treated.
<style> /* In #customization-example we only customize the spacing around the previous and next buttons to group them together */ bespoken-audio-player#customization-example { --prev-next-controls-gap: 0px; } bespoken-audio-player#customization-example::part(prev-button) { border-radius: 2px 0 0 2px; } bespoken-audio-player#customization-example::part(next-button) { border-radius: 0 2px 2px 0; border-left: 0; } </style> <bespoken-audio-player id="customization-example" class="mb-6 border border-gray-300 rounded bg-green-100 block p-5 my-6" playlist-visible tracks='[{"src": "track-1.mp3", "title": "Track One: Introducing the Bespoken Audio Player"}, {"src": "track-2.mp3", "title": "Track 2: This title is too long to display on a single line and should wrap around to the next line if we make the text long enough. This could take quite a lot of text to demonstrate this feature."}, {"src": "track-3.mp3", "title": "Track Three"}]'> </bespoken-audio-player>
Finally, we close with an incredibly ugly example of what's possible with the styling options. View the page
source of this page and look for the styles applied to the player with the id of #the-ugly-version
.