【问题标题】:How to record audio using audioWorklet and AudioWorkletProcessor in javascript?如何在 javascript 中使用 audioWorklet 和 AudioWorkletProcessor 录制音频?
【发布时间】:2019-06-14 06:25:52
【问题描述】:

我有以下逻辑记录(在 AudioContext 中设置采样率 = 16000,仅考虑一个通道进行单声道记录)

  1. 我从 AudioWorklet 设置了一个参数 shouldRecord,根据该参数,AudioWorkletProcessor 将开始将数据放入缓冲区,如下所示
  process(inputs, outputs, parameters) {
    const isRecordingValues = parameters.isRecording;
    //taking first input
    var input0 = inputs[0];
    var inputChannel = input0[0];
    if (isRecordingValues.length ===1){
      const shouldRecord = isRecordingValues[0] === 1;
      if (!shouldRecord && !this._isBufferEmpty()) {

        this._flush();
        this._recordingStopped();
      }

      if (shouldRecord) {
            this._appendToBuffer(inputChannel);
      }

    }
    return true;
  }

}

_appendToBuffer 如下:

  _appendToBuffer(value) {
    if (this._isBufferFull()) {
      this._flush();
    }

    // Here _buffer is of type Float32Array 
    this._buffer.set(value, this._bytesWritten);
    this._bytesWritten += value.length;
  }

  1. 在 _flush 方法中,我将 _buffer 的内容发送到 AudioWorklet,如下所示:
    var blob = this._exportWAV(buffer, this._bytesWritten);
    this.port.postMessage({
      eventType: 'data',
      audioBuffer: blob 
    });

这里的缓冲区包含 -1.0 到 1.0 之间的值。

  1. 我将 AudioWorklet 中的数据作为 ArrayBuffer 对象接收,并将其下载为 Wave 文件。无论文件大小如何,我都可以在 Windows Media Player 中打开文件而不会出错,但持续时间不到一秒,播放结束。

我认为我在 process 方法中做错了,缓冲区中记录的数据格式不正确。

我在这里做错了什么?

【问题讨论】:

  • 缺少太多细节,无法确切知道发生了什么。作为测试,使用缓冲区而不是 blob 发布消息。然后你可以更好地看到正在发生的事情,然后可能会将缓冲区转换为 wav 文件。
  • 如果你把代码放在github上,我们会更容易调查...
  • 我尝试了@RaymondToy 的建议。这样做时,我意识到我将数据从 audioWorklet 发送到烧瓶应用程序的方式是错误的。我应该将 float32Array 或 blob 发送到 Flask 应用程序。在 Flask 应用程序中收到后,我必须将其转换为 16 位浮动数据,这样我才能听到声音。我会在回答中展示我是如何做到的。
  • 很高兴帮助您弄清楚发生了什么!

标签: javascript web-audio-api wave


【解决方案1】:

我将_flush方法改成如下:

_flush() {

  let buffer = this._buffer;
  if (this._bytesWritten < this._bufferSize) {
    buffer = buffer.slice(0, this._bytesWritten);
  }
  this.port.postMessage({
    eventType: 'data',
    audioBuffer: buffer
  });

  this._initBuffer();}

所以我直接将我的缓冲区发送到 AudioWorklet。当我在 AudioWorklet 中收到此缓冲区时,我将其作为 Blob 发送到 Flask 应用程序,如下所示

const audioData = e.data.audioBuffer.buffer;
socket.emit( 'my event', {
   blob : new Blob([audioData], { type: 'audio/wav' })
});

这让我可以在 Flask 应用程序中使用 -1.0 到 1.0 之间的简单浮点数。然后我用下面的函数转换这些浮点数

def convert(raw_floats):
   data = raw_floats
   floats = array.array('f', data)
   samples = [int(sample * 32767)
           for sample in floats]
   raw_ints = struct.pack("<%dh" % len(samples), *samples)
   return raw_ints

我将这些 raw_ints 保存到 WAVE 文件中,该文件可在 Windows Media Player 中播放。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    相关资源
    最近更新 更多