Bespoken Audio Player - Demos

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.

Basic usage

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>
      

Adding multiple tracks

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>

Display only the current track

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>

Using 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>
Play Stop Prev Next

Custom events, handling errors

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.

Customization example: the previous and next buttons

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>

Getting ugly

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.

▶️ ⏸️ ⏮️ ⏭️