如何播放RAW音频文件? [英] How to Play RAW Audio Files?

查看:149
本文介绍了如何播放RAW音频文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在一个项目中,该项目由一个图表组成,该图表显示了另一台设备拾取的音频电平.图表是通过flot API制作的,我具有缩放和选择功能,以便在图表上选择时间范围并放大到所选区域.我的下一步是允许用户收听与图表的该区域相对应的音频.我将音频文件存储在共享服务器上,并且所有文件都单独,逐分钟地存储在RAW数据文件中.我没有在网页中使用音频的经验,目前正在努力完成此任务.据我所知,< audio> HTML标签无法处理RAW数据文件进行播放.我一直在研究Web Audio API,但对它的工作方式和实现方式感到困惑.

I am currently working on a project that consists of a chart that shows audio levels picked up by another device. The charts are made through the flot API and I have zooming and selecting capabilities in order to select a time range on the chart and zoom into that selected region. My next step is to allow the user to listen to the audio that corresponds to that region of the chart. I have the audio files stored on a shared server and all of the files are in individual, minute by minute, RAW data files. I have no experience with using audio in a webpage and am currently struggling on how to complete this task. As far as I have found, the <audio> HTML tag is incapable of processing RAW data files for playback. I have been looking into the Web Audio API but am confused about how it works and how to implement it.

我的第一个问题是如何从服务器解码RAW音频文件并将其显示在HTML页面上以供客户端收听?

My first question is how do I go about decoding RAW audio files from a server and displaying them on an HTML page for a client to listen to?

我的第二个任务是获取与所选范围相对应的所有音频文件,并将它们组合为一个音频输出.例如,如果客户选择的时间范围是1:00 pm-1:50 pm,则我需要每分钟长度访问50个RAW数据音频文件.然后,我想将它们组合在一起以产生一个单一的播放声音.因此,我的第二个问题是,是否有人知道一种顺利完成此操作的方法.

My second task is to grab all of the audio files corresponding to the selected range and combine them into one audio output. For example, if the client selected a time range of 1:00pm - 1:50pm, I would need to access 50 RAW data audio files each a minute in length. I would then want to combine them together to produce one single playback sound. Therefore, my second question is if anyone knows a way to accomplish this smoothly.

感谢您提供任何帮助!

推荐答案

RAW文件已经被解码为PCM音频,但是 Audio 元素不能直接播放PCM.您首先需要将RIFF/WAV标头附加到PCM字节.可以合并多个RAW文件,并在标题中设置总样本/帧长度.50分钟的解码音频将在浏览器中占用大量内存,因此请密切注意并相应地进行测量/优化.

RAW files are already decoded PCM audio, but Audio elements can't play PCM directly. You'll need to append a RIFF/WAV header to the PCM bytes first. Multiple RAW files could be combined, setting the total sample/frame length in the header. 50 minutes of decoded audio will take up a lot of memory in the browser, so keep an eye on that and measure/optimize accordingly.

initAudio()

async function initAudio() {
  // specify your file and its audio properties
  const url = 'https://dev.anthum.com/audio-worklet/audio/decoded-left.raw'
  const sampleRate = 48000
  const numChannels = 1 // mono or stereo
  const isFloat = true  // integer or floating point

  const buffer = await (await fetch(url)).arrayBuffer()

  // create WAV header
  const [type, format] = isFloat ? [Float32Array, 3] : [Uint8Array, 1] 
  const wavHeader = new Uint8Array(buildWaveHeader({
    numFrames: buffer.byteLength / type.BYTES_PER_ELEMENT,
    bytesPerSample: type.BYTES_PER_ELEMENT,
    sampleRate,
    numChannels,
    format
  }))

  // create WAV file with header and downloaded PCM audio
  const wavBytes = new Uint8Array(wavHeader.length + buffer.byteLength)
  wavBytes.set(wavHeader, 0)
  wavBytes.set(new Uint8Array(buffer), wavHeader.length)

  // show audio player
  const audio = document.querySelector('audio')
  const blob = new Blob([wavBytes], { type: 'audio/wav' })
  audio.src = URL.createObjectURL(blob)

  document.querySelector('#loading').hidden = true
  audio.hidden = false
}


// adapted from https://gist.github.com/also/900023
function buildWaveHeader(opts) {
  const numFrames =      opts.numFrames;
  const numChannels =    opts.numChannels || 2;
  const sampleRate =     opts.sampleRate || 44100;
  const bytesPerSample = opts.bytesPerSample || 2;
  const format =         opts.format

  const blockAlign = numChannels * bytesPerSample;
  const byteRate = sampleRate * blockAlign;
  const dataSize = numFrames * blockAlign;

  const buffer = new ArrayBuffer(44);
  const dv = new DataView(buffer);

  let p = 0;

  function writeString(s) {
    for (let i = 0; i < s.length; i++) {
      dv.setUint8(p + i, s.charCodeAt(i));
    }
    p += s.length;
}

  function writeUint32(d) {
    dv.setUint32(p, d, true);
    p += 4;
  }

  function writeUint16(d) {
    dv.setUint16(p, d, true);
    p += 2;
  }

  writeString('RIFF');              // ChunkID
  writeUint32(dataSize + 36);       // ChunkSize
  writeString('WAVE');              // Format
  writeString('fmt ');              // Subchunk1ID
  writeUint32(16);                  // Subchunk1Size
  writeUint16(format);              // AudioFormat
  writeUint16(numChannels);         // NumChannels
  writeUint32(sampleRate);          // SampleRate
  writeUint32(byteRate);            // ByteRate
  writeUint16(blockAlign);          // BlockAlign
  writeUint16(bytesPerSample * 8);  // BitsPerSample
  writeString('data');              // Subchunk2ID
  writeUint32(dataSize);            // Subchunk2Size

  return buffer;
}

body {
  text-align: center;
  padding-top: 1rem;
}
[hidden] {
  display: none;
}
audio {
  display: inline-block;
}

<div id="loading">Loading...</div>
<audio hidden controls></audio>

这篇关于如何播放RAW音频文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆