如何正确缓存 webaudio 对象?

Posted

技术标签:

【中文标题】如何正确缓存 webaudio 对象?【英文标题】:How to cache a webaudio object properly? 【发布时间】:2021-12-14 00:57:48 【问题描述】:

我正在使用 javascript 和其他网络技术开发游戏。在其中,有一个基本上是塔防的游戏模式,其中多个对象可能需要同时使用同一个音频文件(.ogg)。加载一个文件并为每个文件创建一个新的 webaudio 太滞后了,即使我尝试流式传输它而不是简单的同步读取,并且如果我创建一个 webaudio 并将其保存在一个变量中以多次使用,每次它正在播放,并且有一个新的请求来播放所述音频,正在播放的音频将停止以允许新的音频播放(因此,如果有足够的音频,则根本不会播放任何内容)。

由于这些问题,我决定在每次播放时复制所述 webaudio 对象,但这样做不仅速度慢,而且还会造成轻微的内存泄漏(至少我这样做的方式是这样)。

如何正确缓存网络音频以供重复使用?考虑到我很确定我每次都需要一个新的,因为每个音频都有一个位置,因此每个音频的播放方式都会不同,具体取决于播放器相对于正在播放音频的对象的位置

【问题讨论】:

【参考方案1】:

您使用 web-audio-api 标记了您的问题,但从这个问题的正文来看,您似乎使用的是 htmlMediaElement <audio> 而不是 Web Audio API。

所以我会邀请你转换到那个 Web Audio API。

从那里你将能够对你的音频文件进行一次解码,只将解码后的数据保存为 AudioBuffer,并创建 许多 阅读器,它们都将连接到那个唯一的 AudioBuffer,而无需吃掉更多的记忆。

const btn = document.querySelector("button")
const context = new AudioContext();
// a GainNode to control the output volume of our audio
const volumeNode = context.createGain();
volumeNode.gain.value = 0.5; // from 0 to 1
volumeNode.connect(context.destination);

fetch("https://dl.dropboxusercontent.com/s/agepbh2agnduknz/camera.mp3")
  // get the resource as an ArrayBuffer
  .then((resp) => resp.arrayBuffer())
  // decode the Audio data from this resource
  .then((buffer) => context.decodeAudioData(buffer))
  // now we have our AudioBuffer object, ready to be played
  .then((audioBuffer) => 
    btn.onclick = (evt) => 
      // allowing an AudioContext to make noise
      // must be required from an user-gesture
      if (context.status === "suspended") 
        context.resume();
      
      // a very light player object
      const source = context.createBufferSource();
      // a simple pointer to the big AudioBuffer (no copy)
      source.buffer = audioBuffer;
      // connect to our volume node, itself connected to audio output
      source.connect(volumeNode);
      // start playing now
      source.start(0);
    ;
    // now you can spam the button!
    btn.disabled = false;
  )
  .catch(console.error);
<button disabled>play</button>

【讨论】:

以上是关于如何正确缓存 webaudio 对象?的主要内容,如果未能解决你的问题,请参考以下文章

iOS“默认”UIWebView/WebKit 上的 WebAudio 支持

使用纯 JavaScript 和 Chromium WebAudio API 生成音调

删除带有突变的项目时如何正确修改Apollo缓存

如何正确销毁 pthread 互斥锁

WebAudio - 振荡器 setPeridiocWave

使用 WebAudio 合并/混合两个音频流