Creating a personalized audio player using HTML

I have created a design for an audio player that I would like to implement using the HTML audio player element.

https://i.sstatic.net/vJpGg.jpg

When I tried <audio></audio>, it just displayed the default player:

https://i.sstatic.net/nyNj8.jpg

Is there a way to customize the style of the player to match the layout I have designed?

Answer №1

If you're looking to create a customized set of audio controls for an HTML5 player, it's actually quite simple and can be done quickly using basic HTML, CSS, and some light Javascript event handling. This solution will give you a fully-functional custom audio player based on the design provided.

You can find the complete code and example in this jsFiddle: https://jsfiddle.net/mgaskill/zo3ede1c/. Feel free to explore and interact with it as it is a working audio player.

Overview of the Player

The player encompasses all the elements detailed in the original design. You can view this setup (and compare it to the original) in the first image linked below:

https://i.sstatic.net/cixuS.png

In addition to the core design, I added a collapsible "info tray" feature which can be toggled by clicking the "More Info" button on the right side. The second image demonstrates the deployed info tray:

https://i.sstatic.net/n0tT0.png

While there may be slight differences in colors and pixel specifics compared to the original design, the overall structure remains very close to the initial concept. Admittedly, my expertise lies more in functionality than styling, leaving room for enhancements particularly in the CSS aspect. Nonetheless, the player closely mirrors the original design in terms of layout, spirit, and usability.

Tools Used

To facilitate the development process, several external resources were leveraged. These include:

  • jQuery: A personal preference over raw Javascript
  • jQueryUI: Employed for track progress and volume control due to compatibility issues with certain browsers lacking HTML5 progress bar support
  • FontAwesome: Utilized for play/pause and volume/mute button icons
  • Noise Addicts Free MP3 Samples: Specifically, the captivating Semper Fidelis March

HTML Structure

The HTML approach involved treating each component within the audio controls panel as an independent element. The layout itself is fairly straightforward, with the most notable elements being the use of FontAwesome classes for the initial state symbols on the play/pause and volume/mute buttons.

<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<audio id="player">
    <source src="http://www.noiseaddicts.com/samples_1w72b820/2543.mp3" type="audio/mpeg" />
</audio>

<div id="audio-player">
    <div id="controls">
        <i id="play" class="fa fa-pause"></i>
        <span id="start-time" class="time">00:00</span>
        <div id="progressbar"></div>
        <span id="time" class="time">00:00</span>
        <i id="mute" class="fa fa-volume-up"></i>
        <div id="volume"></div>    
    </div>
    <div id="more-info-box">
        <span id="more-info">MORE INFO</span>
    </div>
    <div id="info-tray">
        Track: <span id="track">Semper Fidelis March</span>
    </div>
</div>

All audio controls are encapsulated within the #audio-player element.

CSS Styling

The CSS plays a significant role in bringing the HTML elements to life, providing color schemes, positioning directives, and interactive behaviors.

#audio-player {
    height: 50px;
    width: 500px;
    overflow: hidden;
    background-color: #2B2B2B;
    color: white;
    -webkit-user-select: none; 
    -moz-user-select: none;    
    -khtml-user-select: none;  
    -ms-user-select: none;     
}

#controls {
    height: 50px;
    background-color: #808080;
    width: 350px;
}

.time {
    font-size: 10px;
    color: white;
    position: relative;
    top: 14px;
    margin: 5px;
}

.ui-progressbar {
    background: #2B2B2B;
}

.ui-progressbar-value {
    background: white;
}

#progressbar, #volume {
    height: 10px;
    display: inline-block;
    border-radius: 0px;
    border: none;
    position: relative;
    top: 16px;
}

#progressbar {
    width: 150px;
}

#play, #mute {
    font-size: 16px;
    width: 20px;
    position: relative;
    top: 17px;
}

#play {
    margin-left: 15px;
}

#volume {
    width: 50px;
}

Although most styles are straightforward, certain aspects like text selection prevention and specific layouts require attention. For instance, browser-specific properties disable text selection:

-webkit-user-select: none; 
-moz-user-select: none;    
-khtml-user-select: none;  
-ms-user-select: none;     

Styling for jQueryUI progress bars utilizes pre-defined classes defining different appearance states:

.ui-progressbar {
    background: #2B2B2B;
}

.ui-progressbar-value {
    background: white;
}

Elements' display settings and positional adjustments are made through display: inline-block; and position: relative; rules.

Javascript Implementation

The Javascript portion mainly focuses on managing events related to various controls and statuses.

// JavaScript Code Block

The script contains event handlers for actions such as loading audio metadata, updating track progress during playback, handling user interactions with progress bars, managing play/pause and mute functions, and controlling the visibility of the information tray. Each function caters to a specific aspect of the audio player's behavior and responsiveness.

Answer №2

It is not possible to style the default player, but you have the option to create a custom player using a plugin like plyr.io. With this plugin, you can customize the player's style to suit your needs.

Here's an example:

plyr.setup(document.querySelectorAll('.js-plyr'), {});
<link rel="stylesheet" href="https://cdn.plyr.io/1.6.16/plyr.css">
<script src="https://cdn.plyr.io/1.6.16/plyr.js"></script>

<div class="js-plyr">
  <audio controls="" crossorigin="">
    <source src="https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3" type="audio/mp3">
    <source src="https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg" type="audio/ogg" />
  </audio>
</div>

http://jsbin.com/zajeji/edit?html,js,output

Answer №3

Thank you, Michael Gaskill, for your valuable answer which I have successfully implemented in my project. However, I faced some JS issues when trying to interact with the progress and volume controls. As a result, I made slight modifications to the JS code. If anyone else encounters similar JS problems, feel free to use this revised version. I hope it proves helpful.

Check out the modified JS code here

$(document).ready(function() {
        // JavaScript code goes here...
});
function getTime(t) {
    // Function implementation for getting time
}

function getProgressBarClickInfo(progress_bar, e) {
    // Function implementation for handling progress bar click events
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unconventional border effect while hovering over image within navigation container of Bootstrap

Whenever I hover over the image inside the navigation bar, there is a strange white/gray border that appears. It's quite annoying. Does anyone know how to remove this border? Here is the code snippet causing the issue: <ul class ...

Guide on dynamically displaying a page based on the response from express/mssql middleware

I have developed a full stack application that includes a registration feature which successfully adds data to the database. Now, I am looking for a way to conditionally display the home page based on whether the login credentials are correct. Within my l ...

Shifting the position of an HTML page to one direction

I'm currently working on adding a sidebar to my Twitter Bootstrap 3 project. The goal is to have a fixed positioned nav nav-pills nav-stacked show up on the left side of the page when a button is clicked. I've set its z-index to 1000 so it appear ...

Encountering the error message "value is not defined" when using a React range slider

I recently tried setting up the nodejs react range slider component by following the instructions provided on https://www.npmjs.com/package/react-rangeslider. Despite installing all the necessary dependencies, I keep encountering an error message stating ...

Generating a string indicating the range of days chosen

Imagine a scenario where there is a selection of days available to the user (they can choose multiple). The list includes Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, and Saturday, each with an associated number from 0 to 6. For instance, Sunday ...

Tips for transmitting one or multiple data using jquery.ajax

I found this code on stackoverflow and it is working well for uploading multiple files. However, I am facing an issue where I cannot send additional parameters along with the file upload. Despite trying various methods, I have been unsuccessful in sending ...

MAC Safari is not registering input fields

I'm experiencing a small issue with a form that has two input fields for indicating time (in the format HH:mm) that are very close together, like this: Here is the HTML code snippet: <label> <span>Hour*</span> <input typ ...

Utilizing JSON API data to populate Leaflet maps

I am currently working on fetching JSON data from an API call, extracting the latitude, longitude, and name variables to create a GeoJSON array, and then displaying it on a Leaflet map. Despite not encountering any errors in the console, the geojson appea ...

What is the best way to remove an object element by index within AngularJS?

One of my challenges involves dealing with objects, specifically $scope.formData = {} I am trying to figure out how to remove an element from the object using the index $index: $scope.formData.university[$index]; My attempt was: $scope.formData.univer ...

Color of Bootstrap tooltip arrow outline and fill

How can I customize the background color and border color of the tooltip arrow in Bootstrap 4? $(function() { $('[data-toggle="tooltip"]').tooltip() }) .tooltip-main { width: 15px; height: 15px; border-radius: 50%; font-weig ...

What is the best way to remove a MySQL entry with the help of Ajax and Jquery?

Seeking advice on integrating the post title into a jQuery .ajax call. Successfully able to create and display blog posts, now exploring options for adding delete and edit functionality. Currently focusing on delete as it seems more straightforward. Any su ...

Angular does not assign the ng-invalid-class to the input

In order to register custom validation methods for custom form elements, we use extra directives as shown below: <ng-form name="validatorTestForm"> <our-input-directive name="validatorTest" ng-model="ourModel"/> ...

Resizing Images Responsively Using Bootstrap

I'm working on specifying image sizes for different screen sizes. I'm wondering if there are any specific Bootstrap classes that only work at certain screen sizes. If so, it would be great because then I could use something like <img class = " ...

Utilizing Angular 2's Routerlink with *ngIf and Parameters

Currently, I am facing an issue with a routerlink that includes a parameter: http://localhost:4200/item/1 I am trying to figure out how to implement an *ngIf statement with a parameter.... Here is what I have attempted so far: <div *ngIf="router.url ...

Modify a property within an object and then emit the entire object as an Observable

I currently have an object structured in the following way: const obj: SomeType = { images: {imageOrder1: imageLink, imageOrder2: imageLink}, imageOrder: [imageOrder1, imageOrder2] } The task at hand is to update each image within the obj.images array ...

Firestore - Safely removing a large number of documents without running into concurrency problems

I've encountered issues with my scheduled cloud function for deleting rooms in a Firestore-based game that were either created 5 minutes ago and are not full, or have finished. Here's the code I'm using: async function deleteExpiredRooms() ...

What could be the reason why my AJAX error is not displaying the exception from my Webmethod?

I am currently utilizing Google Chrome for my work tasks. After referring to , I attempted to throw an exception from a webmethod. However, no output is shown in the console.log. The only information I received is a generic error message from the network ...

Why does updating state lead to a re-rendering loop while setting state does not encounter the same issue?

Essentially, I have developed a REST Api that retrieves a list of components (sections) from a CMS along with their associated data. Each section in the UI is assigned a number to indicate its position, but certain sections are excluded from counting, such ...

Conflicting styles arise when using the makeStyles function from Material UI with imported

In working on a React component library using create-react-library, I have incorporated basic components that utilize Material UI components and the material UI hook-based styles pattern. For example (in a simplified form): // LibraryComponent.js const u ...

jQuery does not pass data to bootstrap modal

I am currently working with the full calendar feature. Within this framework, I have implemented a modal that allows users to insert new events: <div id="fullCalModal_add_appointment" class="modal fade"> <div class="modal-dialog"> ...