Is there a way to load and play different sounds on multiple audio players based on the length of an array?

I am attempting to load various sounds (.mp3 audio) on separate audio players that are displayed on a single HTML page. The number of players displayed on the screen is determined by the length of the array. In this specific example, I have 3 elements in the array, resulting in 3 audio players playing different sounds.

I have successfully positioned 3 players vertically on the page, each corresponding to their respective texts (Animal sounds). However, I am encountering the following issues:

  1. Each player plays the same sound instead of incrementing and playing each sound for its designated player. I attempted to use a "for loop" to iterate through the array, but I could not find a way to make it remember the previous audio, causing it to always play the last sound for all players. In this case, only the sound "Cat" is played.

  2. Even when clicking on an empty area between the first and second player where there is no audio player, the sound still plays, and I am unsure as to why...

Any assistance would be greatly appreciated!!!

// Utilize JQuery to select the audio ID and play the audio 
jQuery(document).ready(function() {
var speakWord = document.getElementsByClassName('speakout');
var nowPlaying = speakWord[0];
nowPlaying.load();
$("#divAudio").on("click", function() {
nowPlaying.play();
});
});

var textBox = document.getElementById('inBox');   // Responsible for displaying words
var player = document.getElementById('myPlayer');// Playing the sound (<audio>)
var outArr = ['Dog', 'Cow','Cat'];
var pathArr = ['http://cd.textfiles.com/mmplus/MEDIA/WAV/EFFECTS/BARK.WAV', 'http://www.internetstart.se/download/ljud/moo.wav', 'http://area512.htmlplanet.com/wavs/blackcat.wav'];
var audioLogo = document.getElementById('divAudio');// Resposible for the appearance of the audio player (LOGO)
var img_audio = document.createElement("IMG");// Properties of the IMAGE 
br = document.createElement("br");          // Creating a break in the document 
var new_audio = document.createElement("audio");

var points = 50;

if(outArr.constructor === Array) {
//audioLogo.style.display = "initial";
for(i=0; i < outArr.length; ++i) {

// Regarding the TEXT elements:
textBox.innerHTML += outArr[i]+'<br>';  
textBox.style.fontSize = "30px";
textBox.style.position = "absolute";
textBox.style.top = String(points)+'pt';
textBox.style.marginRight= "5pt";
textBox.style.lineHeight = "71pt";
textBox.style.right = '5pt';
}
}
else {
textBox.innerHTML += outArr;
textBox.style.fontSize = "30px";
textBox.style.position = "absolute";
textBox.style.top = "76pt";
}
var points = 70;
for(i=0; i < pathArr.length; ++i) {
var new_audio = document.createElement("audio");
var multiAud = audioLogo.querySelectorAll('.multiple_audio');

imgArr =  Array(pathArr.length).fill('http://www.coli.uni-saarland.de/~andreeva/powin/images/sound.png');
if(i<1){
img_audio.style.height = "9%";  // The size of the audio logo
img_audio.style.width = "9%";
img_audio.setAttribute("src", imgArr[i]); // Creating an attribute (image) to be added to doc
audioLogo.style.position = "absolute";   
audioLogo.style.top = '58pt';
audioLogo.style.lineHeight = "73pt";
player.src = pathArr[i]; 
audioLogo.appendChild(img_audio); 
audioLogo.innerHTML +=  '<br>';
}
else {
var audio = new Audio(pathArr[i]);
audio.className = 'multiple_audio';
img_audio.style.height = "9%";
img_audio.style.width = "9%";
img_audio.setAttribute("src", imgArr[i]); // Creating an attribute (image) to be added to doc
audioLogo.style.position = "absolute";
audioLogo.style.top = '58pt';
audioLogo.style.lineHeight = "73pt";
audioLogo.appendChild(img_audio);
player.src = pathArr[i]; 
audioLogo.innerHTML +=  '<br>';
// player.parentNode.insertBefore(audio , player.nextNode); 
}

}
#layout {
position: relative;
overflow: auto;
left: 225px;
width: 800px;
height: 370px;
background-color: white;  
padding-left: 1px;
max-width:100%;
}

#myText {
pointer-events: none;
width: 800px;
height: 370px;
resize: none;
font-size: 45px;
font-family: Arial, Helvetica, Verdana;
background: url(https://qph.is.quoracdn.net/main-qimg-47327da6ae3e0b3727a9b9a7ea7f1adb?convert_to_webp=true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<html lang="en">
    <head>
<meta charset="utf-8"/>
    <script type="text/javascript" src="jquery-1.11.3.js"></script>
    </head>
    <body>
<br>
<div id="layout" readonly="readonly">
<div contenteditable maxlength="200" readonly="readonly" id="myText" dir="auto" name="outtest" class = "fetchBox"></div> 
<div id="inBox" class="fetch" dir="auto"></div>

 <audio class="speakout" id="myPlayer"> 

Your Browser does not support the HTML audio Tag!
</audio>

<div class="play" id="divAudio"><img id="play_image"> </div>

</div>

</body>
  
</html>

P.S

  • The audio tags should not display the standard play/pause controls by default. I customized my own player logo; however, for this example, I used a logo from an absolute URL.

  • I attempted to implement suggestions from another post (multiple and dynamic audio players applied for a dictionary in HTML/JavaScript) but encountered challenges. I tried utilizing

    var audio = new Audio(); and

    player.parentNode.insertBefore(audio , player.nextNode);

to address problem 1. It is unclear whether the issue stems from not using the standard player?

Answer №1

Latest Update

Upon the request of the original poster (OP), I have implemented a custom pause/play button to replace the native controls of the HTML5 audio element. Rather than attaching an event listener to each audio element individually, I have utilized a technique explained in this informative article.

  • A new function named handlePlay() is triggered when a click event is detected on the .arrayBox (the container section that houses all the players).

  • The handlePlay() function identifies which button was clicked and then plays or pauses the corresponding audio element located right after the clicked button.

  • I have introduced a new button Object called ybtn which is generated before the creation of an audio element.

    • The styling of these new buttons can be customized using the .btn class.
    • It's worth noting that the button's content is represented by a font symbol:
      • 🔈 &#128264; for off state
      • 🔊 &#128266; for on state
      • This approach is preferred as it loads faster than an image, reducing HTTP requests.

Plunker Demo

Code Snippet

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>DeXY Player</title>
  <style>
    html {
      box-sizing: border-box;
      font: 500 16px/1.428 'Raleway';
      height: 100vh;
      width: 100vw;
    }
    
    *,
    *:before,
    *:after {
      box-sizing: inherit;
      margin: 0;
      padding: 0;
    }
    
    body {
      position: relative;
      font-size: 1rem;
      line-height: 1;
      height: 100%;
      width: 100%;
      overflow-x: hidden;
      overflow-y: auto;
      -webkit-font-smoothing: antialiased;
      background: #222;
      color: #fc2;
    }
    
    button {
      font: inherit;
      line-height: 1.5;
      padding: 1px 3px;
      border-radius: 8px;
      border: 1px solid #00f;
      margin: 20px;
      background: rgba(0, 0, 0, .4);
      color: #00f;
      cursor: pointer;
    }
    
    button:hover {
      border: 1px solid #0ff;
      color: #0ff;
    }

    .btn { /* Custom styles for audio buttons */
      display: inline-block;
    }
  </style>
</head>

<body>
  <h1>DeXY Audio Array Player</h1>
  <button id="btn1">Load</button>
  <section id="arrayBox"></section>
  <script>
// The playList array contains links to various audio files.
 
    var playList = ['URLs-to-audio-files'];

// qty represents the total number of elements in the playList array.

    var qty = playList.length;
    console.log('qty: ' + qty);
  </script>
  <script>
    // JavaScript logic for loading and playing audio elements goes here
  </script>
</body>

</html>

Previous Update

Following a discussion with the OP, I have updated the previous version to include the functionality requested. This revised version now accepts an array of strings as a playlist and consolidates everything into a single function. With just a single click on the button, 31 fully operational audio players appear almost instantly. For more details, refer to the comments within the JS code explaining the loadPlayers() function.

Plunker Demo

Snippet

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>dXPlayer</title>
  <link href='https://fonts.googleapis.com/css?family=Raleway:600' rel='stylesheet' />
  <style>
    html {
      box-sizing: border-box;
      font: 500 16px/1.428 'Raleway';
      height: 100vh;
      width: 100vw;
    }
    
    *,
    *:before,
    *:after {
      box-sizing: inherit;
      margin: 0;
      padding: 0;
    }
    
    body {
      position: relative;
      font-size: 1rem;
      line-height: 1;
      height: 100%;
      width: 100%;
      overflow-x: hidden;
      overflow-y: auto;
      -webkit-font-smoothing: antialiased;
      background: #222;
      color: #fc2;
    }
    
    button {
      font: inherit;
      line-height: 1.5;
      padding: 1px 3px;
      border-radius: 8px;
      border: 1px solid #0ec;
      margin: 20px;
      background: rgba(0, 0, 0, .4);
      color: #0FF;
    }
  </style>
</head>

<body>
  <h1>dX Audio Array Player</h1>
  <section id="arrayBox">
    <button id="btn1">Load</button>
  </section>
  <script>
//This array of strings is a required input needed to run dXPlayer.
 
    var playList = ['URLs-to-audio-files'];
    
//qty is the total quantity of elements within the playList array.

    var qty = playList.length;
    console.log('qty: ' + qty);
  </script>
  <script>
    // JavaScript logic for handling audio elements goes here
  </script>
</body>

</html>



Given the complexity in debugging the code provided by the OP, I have created a functional demo that achieves similar objectives. This demonstration includes:

  • Two event listeners ...
    • one for the DOM Content Loaded event (similar to jQuery's DOM Ready), and ...
    • another for clicking the button (btn1).
  • Two functions ...
    • loadPlayers() gets executed when btn1 is clicked.
      • It fetches all div.snd elements in a NodeList...
      • ... converts them into an Array ...
      • ... and iterates through each element to create unique audio players.
    • xStruct function handles the process of cloning, setting attributes, and assigning content within loadPlayers().

When setting up a project like this, make sure all assets are easily accessible: - Keep all audio files in one directory. - Utilize concise and sequential filenames for easy reference. (e.g., wav1.wav, `wav2.wav, etc..) - Maintain consistency in naming conventions for IDs and classes to avoid errors.

Some prerequisites for running this demo effectively include:

  • For every desired player, ensure there is already a corresponding div in the HTML:

    • IDs should follow a consistent pattern, differing only in numbers.
    • All divs must have the class .snd assigned to them.
  • Match the file names with the IDs set for each div.

Plunker Demo

Code Snippet

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>35529918</title>
  <style>
    section {
      margin: 30px
    }
  </style>
</head>

<body>
  <button id="btn1">Load</button>
  <section>
    <div id="wav1" class="snd"></div>
    <div id="wav2" class="snd"></div>
    <div id="wav3" class="snd"></div>
  </section>
  <script>
    window.addEventListener('DOMContentLoaded', function(e) {

      var btn1 = document.getElementById('btn1');

      btn1.addEventListener('click', loadPlayers, false)

      function loadPlayers() {
        var divList = document.querySelectorAll('.snd');
        var divArray = Array.prototype.slice.call(divList);
        for (var i = 0; i < divArray.length; i++) {
          var ID = divArray[i].id;
          xStruct(ID);
        }
      }

      function xStruct(ID) {
        var xTag = document.createElement('audio');
        var xDiv = document.getElementById(ID);
        var xUrl = 'https://glpjt.s3.amazonaws.com/so/av/';
        var xWav = xUrl + ID + '.wav';
        var xID = ID.substr(1, 3);
        xDiv.appendChild(xTag);
        xTag.setAttribute('id', xID);
        xTag.setAttribute('controls', 'controls');
        xTag.setAttribute('src', xWav);
      }
    }, false);
  </script>
</body>

</html>

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

Setting the font-size in HTML/CSS to dynamically adjust and fill the entire width and height of its

I'm trying to make a <div> element adjust its size based on the browser window. Within this <div>, there is a paragraph of text: <div style="width:80%; height:80%; margin:10%;"> <p>Paragraph of text. Paragraph of text. Pa ...

Is there a way to launch iframe links in the parent window of an Android native app?

I'm currently working on developing a directory-style application, and I am using iframes to embed other websites into the app. I would like the embedded site links to open within the parent window. In the Progressive Web App version, everything is w ...

"Creating dynamic radio buttons within a dynamic table using Ajax and jQuery: a step-by-step guide for toggling

Looking to generate a dynamic html table with data retrieved from a web method in asp.net using Ajax jQuery. One of the fields is a boolean value that needs to be associated with radio buttons. However, encountering an issue where setting attributes like ...

CSS :hover problem, text appearing unexpectedly

I'm currently working on designing a logo that displays hidden text when hovered over, providing instructions to users. However, I've encountered an issue where the hidden text reveals itself even before the logo is hovered over. This is frustrat ...

Is there a way to update the parent value when the child is activated?

I need to create a dropdown menu for users to select their email provider - either gmail, hotmail, or outlook. Once they make a selection, I want the button text to update accordingly. The catch is that I can only use bootstrap for this project and cannot ...

What is the best way for OnSubmit to access an external file?

Recently, I adjusted this code snippet to include the onsubmit attribute with a validation function call. Instead of having the validate function within the same file, I moved it to an external file for better organization. Now, I am wondering how do I e ...

Using Node.js to send instructions to an HTTP server in order to highlight or add color to specific elements within

I have set up a server that receives data from a gaze sensor, as well as an HTTP server that serves an HTML page. I am looking for a way to dynamically highlight elements in the HTML based on the incoming data. Any suggestions on what resources or techniqu ...

Error: Trying to access the 'push' method of an undefined object of useHistory

import React from "react"; import { Route, Switch, HashRouter, useHistory } from "react-router-dom"; import Home from "../pages/home/HomeComponent"; import Splash from "../pages/splash/Splash"; import Education from ...

Enhancing User Interfaces with React and CSS Styling

I need to incorporate two unique React components on my webpage: Component1 and Component2. Code for Page1: <Component1/> <Component2/> While the individual components will have their own CSS files for styling, I also have a page1.css file f ...

Repetitive attempts have led to the cancellation of the AJAX and PHP petition statuses

Whenever I click the button, I am trying to update a MySQL table using AJAX jQuery. Unfortunately, I am encountering a problem where the AJAX jQuery does not work properly sometimes. It starts off fine, but after a certain number of attempts, it stops work ...

Retrieving HTML Source Code in Android Studio

I am having trouble with testing this function even though the permissions are correctly set in the manifest file. Can anyone help me figure out what I'm doing wrong? public void fetchHTMLContent() throws Exception { URL url = new URL("http:/ ...

Using JSDoc and Visual Studio Code: Writing documentation for a function that is being passed as an argument to another

Struggling to properly document the input parameters for a JavaScript function using JSDoc. The documentation suggests using the @callback comment, but Visual Studio Code (VSCode) doesn't seem to recognize it. In VSCode, the intellisense for the loca ...

Tips for maintaining consistent content length of nested divs as one div's content grows

I am looking for a solution to ensure that when the map is running on my MUI card, some cards with more text content will increase in length while maintaining equal text alignment. I have attached a screenshot of my actual app and a CodeSandbox example for ...

Encountering permission issues while attempting to add `@nuxtjs/sentry` in a Docker container running Node 16.14. Installation

While attempting to add @nuxtjs/sentry to my project by running npm install @nuxtjs/sentry, I encountered some issues. Here is the error message I received: npm ERR! code 1 npm ERR! path /app/node_modules/@sentry/cli npm ERR! command failed npm ERR! comm ...

Utilizing React.hydrate in conjunction with Vue: A Beginner's Guide

Wondering about a unique scenario here - I have a website built with Vue and now I aim to showcase a library I developed in React. In order to steer clear of server-side rendering (SSR), I can simply wrap ReactDOM.hydrate(ReactApp, document.getElementById( ...

Creating a promise around a MongoDB instance in Node.js

Currently I am developing a web application where I need to create a MongoDB singleton connection that can be reused in different modules. My approach involves using promises, and so far this is what I have attempted: Server.js module.exports = new Promi ...

Error in Next.js: The function (0 , firebase_auth__WEBPACK_IMPORTED_MODULE_1__.onAuthStateChanged) is not defined as a function

Just starting out with Next.js development and currently following a Youtube tutorial on creating a Whatsapp clone using firebase8.9 as the database. I am looking to implement a feature where the app checks if the user is logged in, if so redirect them to ...

Modify the HTML select tag to toggle from a selected checkbox

What should I do when a certain option is checked in the checkbox, and that label needs to be shown in the select tag? https://i.stack.imgur.com/ZxRNF.png Checkbox input <input type="checkbox" class="toggle-product pull-right" @if(!isset($restrictedPr ...

How can I make sure addEventListener only responds to numbers and not images?

Currently, I am facing a dilemma with implementing a button that features an image on it and needs to be placed within another div. Despite successfully achieving this, I am struggling to comprehend the JavaScript code outlined in a tutorial I followed. Th ...

Dealing with a Nodejs/Express and Angular project - Handling the 404 error

Recently, I decided to dive into learning the MEAN stack and thought it would be a great idea to test my skills by building an application. My goal was simple: display a static variable ('hello') using Angular in the HTML. However, I ran into an ...