Intermittently play a series of sound files, with only the final sound ringing out

My goal is to create an app that plays a sound based on a number input. I have several short MP3 audio files for different numbers, and I want the app to play these sounds in sequence. However, when I try to do this, only the last sound corresponding to the final number is played, and I encounter an error message in the console:

"Uncaught (in promise) DOMException: The play() request was interrupted by a new load request."

I'm unsure of what I am missing or if it's even possible to achieve this. Any assistance would be greatly appreciated.

function playSound(note){

    var currentPlayer;
    var player = document.getElementById("player");

    var isPlaying = player.currentTime > 0 && !player.paused && !player.ended 
&& player.readyState > 2;


     if (!isPlaying){

        player.src = "sounds/"+note+".mp3";
        player.play();

     }else{
        player.pause();
        player.currentTime = 0;
        currentPlayer = player;

     }



}


//variable with numbers where each number should load a sound and play
var numString = "0934590042529689108538569377239609480456034083552";


for(i = 0; i < numString.length; i++){


    switch (parseInt(numString[i])){
        case 1:
            playSound("C"); 
            break;
        case 2:
            playSound("D");
            break;
        case 3:
            playSound("E");
            break;
        case 4:
            playSound("F");
            break;
        case 5:
            playSound("G");
            break;

        case 6:
            playSound("A");
            break;

        case 7:
            playSound("B");
            break;

        case 8:
            playSound("C2");
            break;

        case 9:
            playSound("D2");
            break;


        case 0:
            playSound("silence");
            break;


}

The Html:

<audio controls id="player" style="display: none">
    <source  src="#"></source>
</audio>

Answer №1

Before you can load the next note, you must allow the first one to finish playing:

var index = 0;
var numString = "0934590042529689108538569377239609480456034083552";
var notes = ['silence', 'C', 'D', 'E', 'F', 'G', 'A', 'B', 'C2', 'D2'];
var player = document.getElementById('player');

function playNote() {
  if (index >= numString.length) {
    stop();
    return;
  }
  var note = notes[Number(numString[index])]; // convert number to corresponding note ('1' => 'C')
  if (!note) {
    stop();
    return;
  }
  index++;
  player.src = `sounds/${note}.mp3`;
  player.play();
}

function stop () {
  player.removeEventListener('ended', playNote);
}

player.addEventListener('ended', playNote);
playNote();

Edit:

I have replaced this with player in the playNote function. When playNote() is initially called, there is no this object referring to the player. It should have been playNote.call(player), but it currently works as is.

To minimize the load times between notes, you have two options:

Load sound files separately using multiple audio elements

Create a new Audio() for each note and load the sound file:

var numString = "0934590042529689108538569377239609480456034083552";
var notes = ['silence', 'C', 'D', 'E', 'F', 'G', 'A', 'B', 'C2', 'D2'];
var audios = {};
notes.forEach(note => {
  var audio = new Audio();
  audio.src = `sounds/${note}.mp3`;
  audios[note] = audio;
});

var currentAudio = null;

function playNote () {
  if (currentAudio) {
    currentAudio.removeEventListener('ended', playNote);
  }
  if (index >= numString.length) {
    return;
  }
  var note = notes[Number(numString[index])];
  if (!note) {
    return;
  }
  currentAudio = audios[note];
  index++;
  currentAudio.play();
  currentAudio.addEventListener('ended', playNote);
}

playNote();

Utilize the AudioContext API

The new Web Audio API is more intricate than new Audio() but offers greater capabilities. You can generate various sounds without needing every file on your server by leveraging the client's sound processing abilities.

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

Utilizing Express.js for setting up routes with a default path

In the code snippet below, I am utilizing Express.js: router = express.Router() fs.readdirSync('./controllers').forEach(function (file) { if(file.substr(-3) == '.js') { route = require('./controllers/' + file); ...

Guide to integrating various HTML files into a single HTML file with the help of Vue.js

Although I am familiar with using require_once() in PHP, unfortunately, I am unable to use PHP in my current project. I attempted to use w3-include from W3Schools as an alternative, but encountered issues with loading my scripts. Even utilizing JavaScript ...

Trigger a function when a button is clicked

This is an ongoing project that includes a calculator and other features. Right now, I am working on a functionality where when you input a number into the calculator results and press "+", it should trigger onClick to check if the input was an integer o ...

Is it acceptable to include the bundled main.js file in the gitignore for a HUGO project?

Is it possible to exclude the bundled main.js file from a HUGO project by adding it to .gitignore? ...

Ways to simulate a class instance that is being received from a file with a different class instance

I am struggling with a specific file in my project // src/history import { createBrowserHistory } from 'history' const history = createBrowserHistory(); export default history; The variable history represents an instance of the BrowserHistory cl ...

Unable to access the current state within an asynchronous function in React.js

I have encountered an issue with updating state in the top-level component (App) and accessing the updated state in an asynchronous function defined within useEffect(). Here are more details: The problem arises when I try to retrieve the state of the cons ...

JavaScript change the object into a string

I've been working on code to convert strings into dictionaries and arrays, and vice versa. While string to array and string to object conversions are successful, the reverse process is giving me trouble. I'm currently stuck and unsure of how to r ...

What is the best way to create a function that automatically resumes audio playback 3 seconds after the pause button is clicked?

I am looking to develop a basic webpage with an autoplay audio feature. The page would include a "pause" and "play" button. I aim to implement a function where clicking the "pause" button would stop the audio, but after 3 seconds, it would automatically re ...

Leverage variable as an expression when utilizing ng-include

Here is an example of working code: <div ng-include src="'Test.html'"></div> However, this code does not work: <div ng-include src="ctrl.URL"></div> (When ctrl.URL is set to "Test.html"). I have also tried setting it t ...

What additional requirements are needed for Rails and remote AJAX with the "true" setting?

I'm a bit confused about the purpose of remote:true in Rails forms. I initially thought that it required some Javascript to enable asynchronous functionality, but instead it seems to be causing issues with my page. Below is a simple index.html.haml f ...

Manipulate Angular tabs by utilizing dropdown selection

In my latest project, I have developed a tab component that allows users to add multiple tabs. Each tab contains specific information that is displayed when the tab header is clicked. So far, this functionality is working perfectly without any issues. Now ...

"Ensuring Contact Information is Unique: A Guide to Checking for Existing Email or Phone Numbers in

I'm encountering an issue with validating email and phone numbers in my MongoDB database. Currently, my code only checks for the presence of the email but does not respond to the phone number. const express = require("express"); const router ...

The Controller is encountering an empty child array when attempting to JSON.stringify it

After examining numerous similar questions, I am uncertain about what sets my configuration apart. I've experimented with various ajax data variations and JSON formatting methods, but the current approach seems to be the closest match. This issue is ...

The jQuery keyup event initiates multiple times, increasing exponentially with each trigger

I recently added a search bar with auto-complete functionality to my website. The search bar queries the database for elements that begin with the text entered by the user as they type. Although it works well, I noticed that every time the user inputs ano ...

List of Map Pins on Google Maps

I am looking to integrate PHP and Javascript to display multiple markers (at least 50) on a Google map. After reviewing the documentation at: https://developers.google.com/maps/documentation/javascript/examples/map-latlng-literal I noticed on line 15 it m ...

Selection menu for hierarchical reporting information

Looking for assistance on how to display hierarchical data from two tables - reporting and employee_details. The reporting table includes supervisor_id and subordinate_id fields which correspond to emp_id in the employee_details table. This hierarchy spa ...

Should tabs be closed or redirected after successful authentication with Google?

I have a project that was developed using perl-dancer and angular. The project is integrated with Google as an openID system. On some of the pages, there is an edit grid with a save button. To prevent loss of unsaved data when the session (created from pe ...

avoidable constructor in a react component

When it comes to specifying initial state in a class, I've noticed different approaches being used by people. class App extends React.Component { constructor() { super(); this.state = { user: [] } } render() { return <p>Hi</p> ...

What is the best way to include additional text in a dropdown menu?

I'm trying to add the text "Choose Country" in a drop-down list before the user selects their country. example1 Here is the line of code I used: <option data-hidden="true"> Choose Country </option> However, the phrase does ...

Tips for transforming promise function into rxjs Observables in Angular 10

As a beginner in typescript and angular, I am trying to understand observables. My query is related to a method that fetches the favicon of a given URL. How can I modify this method to use observables instead of promises? getFavIcon(url: string): Observ ...