html - 播放base64音频数据数组

标签 html audio html5-audio

我正在使用JavaScript解析SWF文件并在HTML5 Canvas 中显示内容。

我在播放来自音频流swf标签的音频数据时遇到问题。音频按帧分割,我可以将音频数据按与帧相同的顺序放入base64数据数组中。在每个帧上创建/销毁音频元素似乎并不是解决问题的最佳方法,但这是我能想到的唯一方法。有没有更好的方法来解决这个问题?

注意:swf文件中也有快退/快进/暂停按钮,因此音频在发送回时将需要与帧对齐,因此我不相信我只能从较小的文件中创建一个长音频文件数据位。

最佳答案

您将需要将这些音频文件加载为AudioBuffers并通过Web Audio API播放它们。

您目前拥有的是数据URL,它们确实表示完整的音频文件(带有元数据)。
because some browsers may not let you do so开始,将所有这些都加载到Audio元素中可能确实不是一个好主意,因为HTMLMediaElement并不适合完美的计时。

因此,您将需要首先获取所有这些数据URL,以在ArrayBuffers中获取其实际二进制内容,然后才能从这些音频文件中提取原始PCM音频数据。

// would be the same with data-URLs
const urls = [
  "kbgd2jm7ezk3u3x/hihat.mp3",
  "h2j6vm17r07jf03/snare.mp3",
  "1cdwpm3gca9mlo0/kick.mp3",
  "h8pvqqol3ovyle8/tom.mp3"
].map( (path) => 'https://dl.dropboxusercontent.com/s/' + path );
const audio_ctx = new AudioContext();

Promise.all( urls.map( toAudioBuffer ) )
  .then( activateBtn )
  .catch( console.error );

async function toAudioBuffer( url ) {
  const resp = await fetch( url );
  const arr_buffer = await resp.arrayBuffer();
  return audio_ctx.decodeAudioData( arr_buffer );
}

function activateBtn( audio_buffers ) {
  const btn = document.getElementById( 'btn' );
  btn.onclick = playInSequence;
  btn.disabled = false;
  // simply play one after the other
  // you could add your own logic of course
  async function playInSequence() {
    await audio_ctx.resume(); // to make noise we need to be allowed by a user gesture

    let current = 0;
    while( current < audio_buffers.length ) {
      // create a bufferSourceNode, no worry, it weights nothing
      const source = audio_ctx.createBufferSource();
      source.buffer = audio_buffers[ current ];
      // so it makes noise
      source.connect( audio_ctx.destination );

      // [optional] promisify
      const will_stop = new Promise( (res) => source.onended = res );

      source.start(0); // start playing now

      await will_stop;
      current ++;
    }
  }
}
<button id="btn" disabled>play all in sequence</button>

关于html - 播放base64音频数据数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59062187/

相关文章:

javascript - 使用 native JavaScript,如果对象具有特定的 CSS 类,则更改对象的标题属性

javascript - 如何根据输出 block 更改svg的大小?

android - 在 R.Raw 中打开文件音频

audio - 哪种是 IBM Speech to Text 的最佳声音格式?

javascript - 如何与按键同步播放音频元素?

javascript - 如何在播放下一个音轨时停止此特定音频播放器(HTML5 + JavaScript)

html - 在相邻 block 中底部对齐不同字体大小的文本的正确方法?

javascript - 当管理员单击菜单时,如何在管理仪表板的颜色区域中激活背景颜色,它会进入默认设置的背景颜色

javascript - Phonegap无法读取本地音频文件

reactjs - 无法在 Reactjs 中暂停音频