React js 音频对象未播放 - 媒体资源不合适

问题描述 投票:0回答:7

我正在制作一个钢琴应用程序。我在 React 组件中有一个 js 函数,可以根据提供的注释播放相应的文件,但控制台总是抛出此错误:

未捕获(承诺中)DOMException:src 属性指示的媒体资源或分配的媒体提供程序对象不合适。

并且没有声音播放。这是函数:

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

我的文件结构是:

App
 public
 node_modules
 src
   Components 
          Piano.js
javascript html reactjs audio html5-audio
7个回答
2
投票

确保您的 mp3 文件按照 这些规范 进行编码。您可以使用任何离线或在线工具来检查您的文件信息。也许您刚刚将其他音频文件的扩展名重命名为 mp3。您可以在某处共享您的文件吗? 另外,当用户单击钢琴键时不要加载文件。尝试像这样预加载所有声音文件:


// 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>

我遇到了同样的问题,但不明白为什么它不从文件夹路径接受它。

1
投票
我发现另一个线程,其中有人使用网址作为源,它对我有用。示例网址:

http://streaming.tdiradio.com:8000/house.mp3

我最终将我的声音文件上传到公共亚马逊 s3 存储桶并使用该 url,而 React 应用程序通过使用该 url 来处理我想要的声音。


0
投票

第一:确保您的路径正确!有很多次我只是拼错了一些东西,这导致了一个奇怪/令人困惑的错误。您只需 console.log(path)

看看是否匹配。

第二:在
audio.type("audio/mp3")

之前添加

audio.play

可以帮助你的代码快速知道它要查找的文件类型以及如何读取它。但据我所知,这是可选的。
第三:尝试等待音频文件

这是全部代码:

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); } };

你的路径似乎有问题

0
投票
由于您正在尝试访问文件路径及其在公共文件夹中,请尝试使用此

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

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

或直接使用
访问它

notes/ + note + ".mp3"

让我们看看您的公用文件夹的结构

实现此方案的 2 种方法:


0
投票
只需将任何音频播放器控制器添加到您的文件中,它就应该像在 FireFox 中一样正常工作。

我今天遇到了同样的问题并解决了。

0
投票
我正在使用 [https://vitejs.dev/|vite] 并发现对于不同类型的声音等资源(对我来说是 *.m4a)需要将其添加到 vite 的配置文件中,即 vite.config。 mjs 就像这里提到的

https://vitejs.dev/config/shared-options#assetsinclude

© www.soinside.com 2019 - 2024. All rights reserved.