Version: 2.67.0

How to make an audio-only player?

This article will tell you how to manipulate THEOplayer (Web) to make an audio-only interface, using only CSS and JavaScript.


Web SDKAndroid SDKiOS SDKtvOSAndroid TV SDKChromecast SDK

Code snippets & explanation

The following 7 steps explain how to alter the default video player UI into the UI below.

2.1 Add a new class to 2 HTML elements in the player

We'll provide some CSS code snippets to alter THEOplayer's UI. To make the snippet do the job, we need to add a class to two HTML elements in the player:

  • Add 'audioplayer' to the classList of the player element (select it using the 'vjs-fluid' class)
  • Add 'audiocontrol' to the classList of the controls element (select it using the 'vjs-control-bar' class)
function transformPlayer(forAudio) {
var player = document.querySelector(".vjs-fluid");
var controlbar = document.querySelector(".vjs-control-bar");
if (forAudio) {
} else {

2.2 Hide unnecessary buttons from the control bar (CSS)

There are a bunch of buttons in the control bar that might not be relevant for an audio-only stream. Hence, we'll hide the following buttons using CSS:

  • Subtitles button
  • Quality label
  • Audio menu
  • Cogwheel
  • Fullscreen control
  • Cast button
.audiocontrol .vjs-icon-subtitles,
.audiocontrol .theo-quality-label,
.audiocontrol .vjs-icon-audio,
.audiocontrol .vjs-icon-cog,
.audiocontrol .vjs-fullscreen-control,
.audiocontrol .theo-cast-button,
.audioplayer video {
display: none !important;

2.3 Hide content that might appear above the control bar (CSS)

Now we need to make sure no content appears above our controls. Again, we'll use CSS to hide elements:

  • Poster image
  • Video
  • Metadata (like song info)
.audiocontrol .theoplayer-poster,
.audiocontrol .song-info,
.audioplayer video {
display: none !important;

2.4 Decrease the player's height (CSS)

Next up, decreasing the player height to 50px

.audioplayer {
padding: unset !important;
height: 50px !important;

2.5 Ensure the control bar is always visible (CSS)

By default, the control bar fades away to ensure a better user experience for the video viewer. For audio only, this doesn't make any sense. Some lines of CSS code can make the controls always visible.

.audiocontrol.vjs-control-bar {
visibility: visible !important;
opacity: 1 !important;
display: flex !important;

2.6 Rescale the loading spinner (CSS)

An optional step is to scale the loading icon that spins when the player stalls.

.audioplayer .vjs-loading-spinner {
transform: scale(0.3) !important;

2.7 Change appearance for when the stream is not yet loaded (CSS)

You want to go from this Video view to this 

We're almost there. We just need to remove the giant play-button that shows when the video hasn't started yet.

:not(.vjs-has-started).audioplayer .vjs-big-play-button {
display: none !important;

If we would stop here, the audio player would show 0:00 / 0:00 as time information, since the stream was not yet loaded. This looks a bit clumsy, so we can hide it until the stream has started.

:not(.vjs-has-started).audioplayer .vjs-current-time,
:not(.vjs-has-started).audioplayer .vjs-time-divider,
:not(.vjs-has-started).audioplayer .vjs-duration {
display: none !important;
.vjs-has-started .vjs-current-time,
.vjs-has-started .vjs-time-divider,
.vjs-has-started .vjs-duration {
display: flex !important;


You should end up with a player that looks like this

Sample application