如何将AudioBufferSourceNode设置为音频标签<audio>的音频源?

6
这里有一个方向是可行的 - 我知道您可以使用 createElementSourceNode() 将一个 <audio> 元素的源用于 Web Audio API,以获取音频。是否可能反过来,即使用 AudioBufferSourceNode 作为 <audio> 元素的源呢?
我相当确定这是不可能的,但我一直在查找适用于 AudioBuffers 的默认浏览器音频元素播放控件的 npm 标准外观,无花里胡哨的重新创建,但我没有找到任何东西。

你的意思是在node.js中吗?web-audio-api和HTMLAudioElements都是为浏览器设计的。 - Kaiido
抱歉 - 我正在使用node.js和babel来打包所有内容,可能应该去掉那个标签。这一切都发生在浏览器上。 - Tinstar
你为什么需要这个?毕竟,如果你有一个AudioBufferSourceNode,就已经有了一个AudioContext,你可以将节点插入到AudioContext的输出中并获得声音输出。 - AKX
大多数时候,我只是播放一个大的音频精灵文件的片段,但如果用户想查看对象的更多信息,我希望给他们播放该对象音频的能力,并提供标准音频控件。我会将其他所有背景声音静音。我不需要它在<audio>标签中,我只是很难找到一个可以在<audio>标签之外模拟这些控件的库。 - Tinstar
1个回答

5
你可以将AudioBufferSourceNode连接到MediaStreamDestination节点,然后使用该节点的.stream属性向HTMLAudioElement srcObject提供数据:

start.onclick = e => {

  const audioCtx = new AudioContext();
  fetch("https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3")
  .then(resp => resp.arrayBuffer())
  .then(buf => audioCtx.decodeAudioData(buf))
  .then(audioBuffer => {
    const source = audioCtx.createBufferSource();
    source.buffer = audioBuffer;
    source.playbackRate.value = 0.1;
    source.loop = true;
    source.start(0);
    const streamNode = audioCtx.createMediaStreamDestination();
    source.connect(streamNode);
    const audioElem = new Audio();
    audioElem.controls = true;
    document.body.appendChild(audioElem);
    audioElem.srcObject = streamNode.stream;
  })
  .catch(console.error);
}
<button id="start">start</button>


1
有趣的是,它似乎在循环时不断地向播放栏添加时间,而不是在重新启动时将播放头跳回开头? - Tinstar
1
这是因为正在播放的是一个MediaStream。这个MediaStream本身是由循环的AudioBufferSource提供的。 - Kaiido
@Kaiido 对不起回复晚了 - 我对这些东西还不太熟悉 - 如果我将循环设置为 false,那么我该如何让音频元素在连接的缓冲区结束时停止播放? - lukep

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接