Examples

Common patterns and tips for building custom UIs with primitives.

Minimal Player

A play button and progress bar. The simplest possible custom player.

<fortyfour-recording
  id="rec"
  recording-id="YOUR_RECORDING_ID"
  preload="metadata"
></fortyfour-recording>

<div style="display: flex; align-items: center; gap: 8px;">
  <fortyfour-play-button for="rec"></fortyfour-play-button>
  <fortyfour-progress-bar
    for="rec"
    style="flex: 1;"
  ></fortyfour-progress-bar>
</div>

All the primitives together: play button, waveform, duration, transcription, and translation.

<fortyfour-recording
  id="demo"
  recording-id="YOUR_RECORDING_ID"
  preload="metadata"
></fortyfour-recording>

<div style="display: flex; align-items: center; gap: 12px;">
  <fortyfour-play-button
    for="demo"
    shape="circle"
    visualization="ring"
  ></fortyfour-play-button>

  <div style="flex: 1;">
    <fortyfour-bar-waveform for="demo"></fortyfour-bar-waveform>
  </div>

  <fortyfour-duration
    for="demo"
    format="remaining"
  ></fortyfour-duration>
</div>

<fortyfour-transcription
  for="demo"
  mode="karaoke"
  max-height="120"
></fortyfour-transcription>

<fortyfour-translation
  for="demo"
  max-height="80"
></fortyfour-translation>

Line Waveform Player

Swap the bar waveform for a line waveform. Use the sharp attribute for straight lines.

<fortyfour-recording
  id="line-demo"
  recording-id="YOUR_RECORDING_ID"
  preload="metadata"
></fortyfour-recording>

<div style="display: flex; align-items: center; gap: 12px;">
  <fortyfour-play-button for="line-demo"></fortyfour-play-button>

  <fortyfour-line-waveform
    for="line-demo"
    line-width="2"
    height="48"
    style="flex: 1;"
  ></fortyfour-line-waveform>

  <fortyfour-duration for="line-demo"></fortyfour-duration>
</div>

Multiple Recordings

Each recording element gets its own ID. Primitives link to the right one using for. Use the play event to pause other recordings when one starts.

<fortyfour-recording
  id="rec-1"
  recording-id="RECORDING_1"
  preload="metadata"
></fortyfour-recording>
<div style="display: flex; align-items: center; gap: 8px;">
  <fortyfour-play-button for="rec-1"></fortyfour-play-button>
  <fortyfour-bar-waveform
    for="rec-1"
    style="flex: 1;"
  ></fortyfour-bar-waveform>
</div>

<fortyfour-recording
  id="rec-2"
  recording-id="RECORDING_2"
  preload="metadata"
></fortyfour-recording>
<div style="display: flex; align-items: center; gap: 8px;">
  <fortyfour-play-button for="rec-2"></fortyfour-play-button>
  <fortyfour-bar-waveform
    for="rec-2"
    style="flex: 1;"
  ></fortyfour-bar-waveform>
</div>

<script>
document.addEventListener('play', (e) => {
  if (e.target.tagName !== 'FORTYFOUR-RECORDING') return;
  document.querySelectorAll('fortyfour-recording').forEach((rec) => {
    if (rec !== e.target) rec.pause();
  });
}, true);
</script>

Subtitle-Style Transcription

Use mode="subtitle" to show one sentence at a time, like video subtitles.

<fortyfour-recording
  id="sub-demo"
  recording-id="YOUR_RECORDING_ID"
  preload="metadata"
></fortyfour-recording>

<fortyfour-play-button for="sub-demo"></fortyfour-play-button>

<fortyfour-transcription
  for="sub-demo"
  mode="subtitle"
></fortyfour-transcription>

Custom Styling

Each primitive has CSS variables for colors and sizing. Here is a dark themed player using custom colors.

fortyfour-play-button {
  --fortyfour-play-button-background-color: #1db954;
  --fortyfour-play-button-icon-color: #ffffff;
  --fortyfour-play-button-size: 40px;
}

fortyfour-bar-waveform {
  --waveform-progress-color: #1db954;
  --waveform-track-color: #404040;
}

fortyfour-duration {
  color: #b3b3b3;
  font-size: 12px;
}

fortyfour-transcription {
  --transcription-text-color: #ffffff;
  --transcription-highlight-color: #1db954;
}

Learn More

Overview

What primitives are and how they connect

Playground

Experiment with settings interactively