【问题标题】:How convert a audio file into byte array with javascript如何使用 javascript 将音频文件转换为字节数组
【发布时间】:2018-08-11 23:05:12
【问题描述】:

我正在尝试将 .wav 文件转换为字节数组字符串。我需要在后端执行此操作,目标文件正在成为一个问题。

        files.forEach(file => {
            let index = files.indexOf(file)
            let reader = new FileReader();
            reader.readAsArrayBuffer(file);
            console.log(reader.result);

            reader.onload = function (event) {
                let byteArray = new Uint8Array(reader.result);
                let FileName = file.name;
                let dataAsByteArrayString = byteArray.toString();
                var listHtml = $list.html();

上面的代码使用了 npm 的文件阅读器,它说目标文件。我很难做到这一点,因为这不是文件的前端拖放。

我生成的文件名为“response.wav”我将如何使用 JavaScript 和节点扩展转换此文件?谢谢!

【问题讨论】:

  • 转成byte array string?
  • 是 如:DataAsByteArrayString':'82,73,70,70,255,255,255,255,87,65,86,69,102,109,116,32,16,0,0,0,1,0,1,0, 34,86,0,0,68,172,0,0,2,0,16,0,76,73,83,84,26,0,0,0,73,78,70,79,73,83, 70,84,14,0,0,0,76,97,118,102,53,55,46,55,49,46,49,48,48,0,100,9
  • 您是在尝试实际解析 WAV 文件,还是只需要一般地读取文件?

标签: javascript node.js file-conversion


【解决方案1】:

我不知道这是否会有所帮助,但我从事的最后一个项目是使用 Node 缓冲区 API 解析一个 .wav 文件并使用 Node 文件 API 编写它。 如果您对代码有更多疑问,我可以将您定向到处理此文件最多的人。我希望它有所帮助 https://github.com/IntelliSound/intelliSound-Server/blob/development/lib/sound-data-parser.js

'use strict';

function ParsedWave(buffer) {
  
  const RIFF_HEADER_OFFSET = 0;
  const FILE_SIZE_OFFSET = 4;
  const RIFF_FORMAT_OFFSET = 8;
  const SUBCHUNK1_ID_OFFSET = 12;
  const AUDIO_FORMAT_OFFSET = 20;
  const NUMBER_OF_CHANNELS_OFFSET = 22;
  const SAMPLE_RATE_OFFSET = 24;
  const BITS_PER_SAMPLE_OFFSET = 34;
  const SUBCHUNK2_ID_OFFSET = 36;
  const SUBCHUNK2_SIZE_OFFSET = 40;
  const DATA_OFFSET = 44;
  
  this.buffer = buffer;
  this.riff = buffer.slice(RIFF_HEADER_OFFSET, RIFF_HEADER_OFFSET + 4).toString('utf8');
  this.fileSize = buffer.readUInt32LE(FILE_SIZE_OFFSET);
  this.riffType = buffer.slice(RIFF_FORMAT_OFFSET, RIFF_FORMAT_OFFSET + 4).toString('utf8');
  this.subChunk1Id = buffer.slice(SUBCHUNK1_ID_OFFSET, SUBCHUNK1_ID_OFFSET + 4).toString('utf8');
  this.audioFormat = buffer.readUInt16LE(AUDIO_FORMAT_OFFSET);
  this.numberOfChannels = buffer.readUInt16LE(NUMBER_OF_CHANNELS_OFFSET);
  this.sampleRate = buffer.readUInt32LE(SAMPLE_RATE_OFFSET);
  this.bitsPerSample = buffer.readUInt16LE(BITS_PER_SAMPLE_OFFSET);
  this.subChunk2Id = buffer.slice(SUBCHUNK2_ID_OFFSET, SUBCHUNK2_ID_OFFSET + 4).toString('utf8');
  this.subChunk2Size = buffer.readUInt32LE(SUBCHUNK2_SIZE_OFFSET);
  this.data = buffer.slice(DATA_OFFSET, this.subChunk2Size + DATA_OFFSET);
}

// Andrew - The bufferMapper function is going to accept a parsed wave-file and output
//          an array of values corresponding to the data subchunk in a format which can
//          be accepted as input to the neural network.

const bufferMapper = parsedWave => {
  
  const SIXTEEN_BIT_ZERO = 32768;
  const SIXTEEN_BIT_MAX = 65535;
  
  parsedWave.neuralArray = [];
  
  for (let i = 0; i < parsedWave.data.length; i += 2) {
    const sample = parsedWave.data.readInt16LE(i);
    const unsignedSample = sample + SIXTEEN_BIT_ZERO;
    const sigmoidSample = unsignedSample / SIXTEEN_BIT_MAX;
    parsedWave.neuralArray.push(sigmoidSample);
  }
  return parsedWave;
};

module.exports = data => {

  const parsedWaveFile = new ParsedWave(data);

  if (parsedWaveFile.riff !== 'RIFF') {
    throw new TypeError('incorrect file type, must be RIFF format');
  }

  if (parsedWaveFile.fileSize > 10000000) {
    throw new TypeError('file too large, please limit file size to less than 10MB');
  }

  if (parsedWaveFile.riffType !== 'WAVE') {
    throw new TypeError('file must be a WAVE');
  }

  if (parsedWaveFile.subChunk1Id !== 'fmt ') {
    throw new TypeError('the first subchunk must be fmt');
  }

  if (parsedWaveFile.audioFormat !== 1) {
    throw new TypeError('wave file must be uncompressed linear PCM');
  }

  if (parsedWaveFile.numberOfChannels > 2) {
    throw new TypeError('wave file must have 2 or less channels');
  }

  if (parsedWaveFile.sampleRate > 48000) {
    throw new TypeError('wave file must have sample rate of less than 48k');
  }

  if (parsedWaveFile.bitsPerSample !== 16) {
    throw new TypeError(`file's bit depth must be 16`);
  }

  if (parsedWaveFile.subChunk2Id !== 'data') {
    throw new TypeError('subchunk 2 must be data');
  }

  const neuralMappedWaveFile = bufferMapper(parsedWaveFile);

  return neuralMappedWaveFile;
};

【讨论】:

    【解决方案2】:

    使用包含的fs module,您可以像这样读取您的wav文件:

    const fs = require('fs');
    const path = './path/to/my.wav';
    
    fs.readFile(path, (err, data) => {
        // Data is a Buffer object 
    
    });
    

    有关使用 Node.JS Buffer see here 的文档。现在,如果您对文件转换部分更感兴趣,那里有几个库。如果您只需要转换功能,而不是自己实现,node-fluent-ffmpeg 可能适合您。如果你想自己实现它,这个node-wav file 可能是一个很好的参考(这里粘贴太多了)。

    如果您需要从 Buffer 转到 ArrayBuffer,这个SO 显示了一些选项。

    【讨论】:

    • 谢谢!这有很大帮助。我能够使用 with! 从缓冲区转到 arrayBuffer!
    猜你喜欢
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多