Audio player

PRESTOplay isn’t just for video. Pass an <audio> element to the player and you get the same adaptive streaming, DRM, and playback API for podcasts, radio streams, and music.

The Player accepts any HTMLMediaElement, so an <audio> element works wherever the documentation uses a <video> element. Install and import the same components as for video playback — see Getting started and Components.

Create the player

Add an <audio> element to the page:

<audio id="audio" controls crossorigin="anonymous"></audio>

Create the player with the disableContainer option:

import { clpp } from "@castlabs/prestoplay";
import "@castlabs/prestoplay/cl.mse";
import "@castlabs/prestoplay/cl.dash";
import "@castlabs/prestoplay/cl.hls";

const player = new clpp.Player("audio", {
  license: "<your_license_key>",
  viewerId: "<user_id>",
}, { disableContainer: true });

By default, the player wraps the media element in a container <div> and positions the media element absolutely inside it (see Player surface). The container then takes its size only from its own styles. Video layouts set that size, but with an <audio> element the container collapses to zero height and hides the native audio controls. With disableContainer: true, the <audio> element stays in the page layout as is.

Keep the container only if you need a feature that renders into it, such as HTML subtitles, ad overlays, or HLS interstitials. In that case, give the container an explicit height, for example:

.clpp-container {
  height: 54px;
}

Load audio content

Load content with Player.open, the same as for video:

await player.open({
  source: "https://demo.cf.castlabs.com/media/HLS/Non-Muxed/unencrypted/audio/prog_index.m3u8",
});

If the manifest also contains video, set streaming.disableVideoTracks so the player discards the video tracks and downloads only audio:

await player.open({
  source: "https://example.com/manifest.mpd",
  streaming: {
    disableVideoTracks: true,
  },
});

disableVideoTracks applies only to MSE playback, not to native playback such as Safari HLS or Tizen, and only to streams with separate audio and video tracks. It doesn’t remove video from multiplexed audio and video streams. In these cases, use a manifest that contains audio-only renditions. Otherwise, the player downloads video segments that an <audio> element never displays.

For HLS through MSE, raw AAC segments (.aac) and MPEG transport stream (MPEG-TS) segments require mux.js on window.muxjs:

import * as muxjs from "mux.js";
window.muxjs = muxjs;

See HLS through MSE for installation details.

DRM-protected audio uses the same drm configuration as video. See DRM.

Build custom controls

Native controls are the quickest way to get started. For a branded player, remove the controls attribute and drive your own UI through the player API.

Drive the controls through Player.play, Player.pause, Player.seek, Player.setVolume, and Player.setMuted, and update them from these events:

  • clpp.events.STATE_CHANGED for the play/pause state

  • timeupdate for the position, using Player.getSeekRange so the seek bar also covers live streams

  • volumechange for the volume and muted state

The audio player sample is a complete page with play/pause, a seek bar, elapsed time, volume, and mute controls for an audio-only HLS stream.

To let listeners switch between audio languages or qualities, use the TrackManager. See Tracks and languages.

Limitations

Features that render video or overlays don’t apply to an <audio> element:

  • Picture-in-Picture and fullscreen

  • Subtitles: browsers don’t render text tracks on <audio> elements, and HTML subtitles require the player container

  • Ad and interstitial UI, which requires the player container

Next topic: Events
Previous topic: Player surface