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

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

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

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

【问题讨论】:

    标签: javascript caching web-audio-api


    【解决方案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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2018-09-10
      • 1970-01-01
      • 2023-03-28
      相关资源
      最近更新 更多