Areze
Areze

Reputation: 91

React js audio object not playing - The media resource was not suitable

I am making a piano app. I have a js function in a react component that plays the corresponding file to the note provided but the console always throws this error:

Uncaught (in promise) DOMException: The media resource indicated by the src attribute or assigned media provider object was not suitable.

And no sound is played. Here is the function:

var handleClick = (note) => {
    var path = "../../public/notes/" + note + ".mp3";
    var audio = new Audio(path);
    audio.play(); 
    console.log(audio);
    return audio.play();
  };

Also my file structure is:

App
 public
 node_modules
 src
   Components 
          Piano.js

Upvotes: 4

Views: 12475

Answers (8)

milad sadeghi
milad sadeghi

Reputation: 24

You need to use a source tag inside the audio element like this:

<audio
  ref={audioRef}
  onDurationChange={(e) => handleDuration(e.currentTarget.duration)}
  onEnded={handleOnEnd}
  onTimeUpdate={(e) => updateCurrentTime(e.currentTarget.currentTime)}
>
  <source src={trackSrc} type="audio/mpeg" />
    Your browser does not support the audio element.
</audio>

Upvotes: 0

Waqas Ahmed
Waqas Ahmed

Reputation: 321

I faced same problem today and resolved it.

I'm using [https://vitejs.dev/|vite] and found out that for assets like sound of different types (For me its *.m4a) need to add that within configuration file of vite i.e vite.config.mjs like mentioned here https://vitejs.dev/config/shared-options#assetsinclude

Upvotes: 0

Fidel C
Fidel C

Reputation: 11

I ran into the same problem and couldn't figure out why it wouldn't accept it from folder path.

I found another thread where someone used a url as the source and it worked for me. Example url: http://streaming.tdiradio.com:8000/house.mp3

I ended up uploading my sound file to a public amazon s3 bucket and using the url and the react app worked with my desired sound like that, by using the url.

Upvotes: 1

Borna GB
Borna GB

Reputation: 31

I think the answer is very simple, so much that makes me feel weird repeating it. Chrome does not allow media playing unless it has controls. Your code is just calling the media while the client does not have access to pausing or stopping it.

Simply add any audio player controller to your file and it should work just fine as it does in FireFox.

Upvotes: 0

Paiman Rasoli
Paiman Rasoli

Reputation: 1214

2 ways for implementing this senario:

1- using UIFX package:

// Note: Player.js and music file located in src

import music from './music.mp3'
import UIFx from "uifx";
export default function Player(){
  const sound = new UIFx(music , {
      volume: 0.8,
   });
   sound.play();
 // 2-way => custom function
const playTheSound = () =>{
 var audio = new Audio(music);
 audio.play();
// it works in FireFox but chrome raise error that you can not play manualy.
 }
 return <p>Player</p>
}

Upvotes: 0

Ridwan Ajibola
Ridwan Ajibola

Reputation: 1089

Seems there's a problem with your path

Since you are trying to access the file path and its in your public folder, try using this

process.env.PUBLIC_URL + "/notes/" + note + ".mp3"

or

window.location.origin + "/notes/" + note + ".mp3"

or access it directly using

notes/ + note + ".mp3"

Let's see how your public folder is structured

Upvotes: 0

the Hutt
the Hutt

Reputation: 18408

Make sure your mp3 files are encoded as per these specifications. You can use any offline or online tool to check your file info.
Maybe you've just renamed the extension to mp3 of some other audio file. Can you share your file somewhere?

Also, don't load files when user clicks on piano keys. Try to preload all sound files like this:

// handle all promise rejections
window.onunhandledrejection = function(event) {
  console.log(`Reason: ${event.reason}`,
    ` Return value: ${event.returnValue}`
  );
};


let mouseDown = false;
let sounds = {
  a: "https://freesound.org/data/previews/448/448573_9311684-lq.mp3",
  b: "https://freesound.org/data/previews/448/448565_9311684-lq.mp3",
  c: "https://freesound.org/data/previews/448/448540_9311684-lq.mp3",
  d: "https://freesound.org/data/previews/448/448600_9311684-lq.mp3",
}

// preload audio files
let promises = [];
Object.keys(sounds).forEach(s => {
  promises.push(new Promise((resolve, reject) => {
    let url = sounds[s];
    sounds[s] = new Audio();
    sounds[s].addEventListener('canplaythrough', resolve, false);
    sounds[s].src = url;
  }));
});

Promise.all(promises).then(() => {
  stats.innerText = `All audio files loaded!  Drag mouse over the keys 😋`;
  stats.style.color = 'green';
  init();
}).catch(e => {
  console.log('error loading audio files: ', e);
  stats.innerText = 'Error loading audio files, see console logs.'
});


function init() {
  Object.keys(sounds).forEach(s => {
    document.querySelectorAll(`.${s}`).forEach(k => {
      k.addEventListener('mousedown', () => {
        sounds[s].play();
      });

      k.addEventListener('mouseenter', () => {
        if (mouseDown)
          sounds[s].play();
      });

      k.addEventListener('mouseup', () => {
        sounds[s].currentTime = 0;
        sounds[s].pause();
      });
      k.addEventListener('mouseleave', () => {
        sounds[s].currentTime = 0;
        sounds[s].pause();
      });
    })
  });

  piano.addEventListener('mousedown', () => mouseDown = true);
  piano.addEventListener('mouseup', () => mouseDown = false);
  piano.addEventListener('mouseleave', () => mouseDown = false);

}
* {
  box-sizing: border-box;
  margin: 0;
}

.piano {
  height: 100px;
  width: 100vw;
  padding: 0 1rem 0 1rem;
}

.key {
  float: left;
  max-width: 50px;
  width: 10%;
  height: 100%;
  padding-bottom: .5rem;
  margin-right: 0px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  border: 1px solid gray;
  border-radius: 0 0 .6rem .6rem;
  cursor: pointer;
  user-select: none;
  color: gray;
}

.key:hover {
  box-shadow: inset -2px 0px 1px 3px wheat;
}

.key:active {
  box-shadow: inset -3px 0px 1px 2px rgb(212, 180, 120);
}

#stats {
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  color: darkred;
}
<div id="piano" class="piano">
  <div class="key a">A</div>
  <div class="key b">B</div>
  <div class="key c">C</div>
  <div class="key d">D</div>
  <div class="key a">A</div>
  <div class="key b">B</div>
  <div class="key c">C</div>
  <div class="key d">D</div>
</div>

<div id="stats">Loading audio...</div>

Upvotes: 2

MakeMeSenpai
MakeMeSenpai

Reputation: 1

It might be your path, but try await

1st: Make sure your paths are correct! There have been so many times where I just misspelled something and it caused a weird/ confusing error. You can simply console.log(path) and see if it matches.

2nd: Adding audio.type("audio/mp3") before audio.play can help your code quickly know what type of file it's looking for and how to read it. But from what I've seen this is optional.

3rd: try awaiting the audio file

Here is the code all together:

var handleClick = async (note) => {
    var path = "../../public/notes/" + note + ".mp3";
    var importRes = await import(path);
    var audio = new Audio(importRes.default);
    audio.type = "audio/mp3";
    try {
        await audio.play();
        console.log("Playing audio" + audio);
    } catch (err) {
        console.log("Failed to play, error: " + err);
    }
 };

Upvotes: 0

Related Questions