Как записать аудио с помощью AudioWorklet и AudioWorkletProcessor в JavaScript? - PullRequest
1 голос
/ 14 июня 2019

У меня ниже логика для записи (установите частоту дискретизации = 16000 в AudioContext, запись моноканала с учетом только одного канала)

  1. Я установил параметр shouldRecord из AudioWorklet, и в зависимости от этого 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 без ошибок, но он длится менее секунды и воспроизведение заканчивается.

Мне кажется, я что-то не так делаю в методе process, а данные, записанные в буфере, имеют неправильный формат.

Что я здесь не так делаю?

1 Ответ

0 голосов
/ 24 июня 2019

Я изменил метод _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 to Flask, как показано ниже

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

, это дает мне простые простые числа с плавающей точкой от -1,0 до 1,0 для работы в приложении Flask.Затем я конвертирую эти числа с плавающей запятой с помощью функции ниже

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.

...