如何在javascript中使用audioWorklet和AudioWorkletProcessor录制音频?

时间:2019-06-14 06:25:52

标签: javascript web-audio wave web-audio-api

我有以下逻辑进行记录(在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方法中做错了,缓冲区中记录的数据格式不正确。

我在这里做什么错了?

1 个答案:

答案 0 :(得分:0)

我将_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中播放。