最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to save Int16Array buffer to wav file node js - Stack Overflow

programmeradmin2浏览0评论

I am sending Int16Array buffer to server while audio processing

var handleSuccess = function (stream) {
        globalStream = stream;
        input = context.createMediaStreamSource(stream);
        input.connect(processor);

        processor.onaudioprocess = function (e) {
            var left = e.inputBuffer.getChannelData(0);
    var left16 = convertFloat32ToInt16(left);
    socket.emit('binaryData', left16);
        };
    };

    navigator.mediaDevices.getUserMedia(constraints)
        .then(handleSuccess);

and in server i am trying to save the file as follows

client.on('start-audio', function (data) {
        stream = fs.createWriteStream('tesfile.wav');
    });

    client.on('end-audio', function (data) {
         if (stream) {
            stream.end();
         }
         stream = null;
    });

    client.on('binaryData', function (data) {
        if (stream !== null) {
            stream.write(data);
        }
    });

But this is not working so how i save this array buffer as wav file?

I am sending Int16Array buffer to server while audio processing

var handleSuccess = function (stream) {
        globalStream = stream;
        input = context.createMediaStreamSource(stream);
        input.connect(processor);

        processor.onaudioprocess = function (e) {
            var left = e.inputBuffer.getChannelData(0);
    var left16 = convertFloat32ToInt16(left);
    socket.emit('binaryData', left16);
        };
    };

    navigator.mediaDevices.getUserMedia(constraints)
        .then(handleSuccess);

and in server i am trying to save the file as follows

client.on('start-audio', function (data) {
        stream = fs.createWriteStream('tesfile.wav');
    });

    client.on('end-audio', function (data) {
         if (stream) {
            stream.end();
         }
         stream = null;
    });

    client.on('binaryData', function (data) {
        if (stream !== null) {
            stream.write(data);
        }
    });

But this is not working so how i save this array buffer as wav file?

Share Improve this question edited Apr 10, 2020 at 13:09 Ravimallya 6,6102 gold badges44 silver badges76 bronze badges asked Jul 18, 2018 at 10:01 azharazhar 1,7572 gold badges19 silver badges41 bronze badges 5
  • 1 I need to do the same... Did you have a solution now? – Ranjith Kumar Commented Oct 23, 2019 at 12:19
  • I've tried to use this github./Jam3/audiobuffer-to-wav but without any luck. – Ravimallya Commented Apr 10, 2020 at 13:11
  • @Ravimallya is there a reproductive example in a repository maybe? Does this uses socket.io? – Christos Lytras Commented Apr 11, 2020 at 19:44
  • Yes @ChristosLytras, Here's a git github./ravimallya/angular-node-google-voice-api . nodejs server code (socket.io) inside /bin directory and audio recorder is inside src/app/dashboard ponent. I'm sending left16 array buffer. Live transcription works fine. However, I need to save recorded audio as wav file in server. – Ravimallya Commented Apr 12, 2020 at 5:56
  • 1 @Ravimallya please check my answer and the repository with a simple project that demonstrates the usage of the wav NPM package on server side. – Christos Lytras Commented Apr 12, 2020 at 22:03
Add a ment  | 

1 Answer 1

Reset to default 6 +200

At the O/P question, there is an attempt to write and add data directly to an existing file which it can't work because WAVE files need to have a header and there can't be a header by just creating a write file stream using createWriteStream. You can check about that header format here "WAVE PCM soundfile format".

There is the wav NPM package which it can help to handle the whole process of writing the data to the server. It has the FileWriter class which creates a stream that will properly handle WAVE audio data and it will write the header when the stream ends.

1. Create a WAVE FileWriter stream on start-audio event:

// Import wav package FileWriter
const WavFileWriter = require('wav').FileWriter;

...

// Global FileWriter stream.
// It won't handle multiple client connections; it's just for demonstration
let outputFileStream;

// The UUID of the filename that's being recorded
let id;

client.on('start-audio', function() {
  id = uuidv4();

  console.log(`start-audio:${id}`);

  // Create a FileWriter stream using UUID generated for filename
  outputFileStream = new WavFileWriter(`./audio/recs/${id}.wav`, {
    sampleRate: 16000,
    bitDepth: 16,
    channels: 1
  });
});

2. Use the stream we created to write audio data on binaryData event:

client.on('binaryData', function(data) {
  console.log(`binaryData:${id}, got ${data ? data.length : 0} bytes}`);

  // Write the data directly to the WAVE file stream
  if (outputFileStream) {
    outputFileStream.write(data);
  }
});

3. End the stream when we receive end-audio event:

client.on('end-audio', function() {
  console.log(`end-audio:${id}`);

  // If there is a stream, end it.
  // This will properly handle writing WAVE file header
  if (outputFileStream) {
    outputFileStream.end();
  }

  outputFileStream = null;
});

I have created a Github repository with this example which you can find here: https://github./clytras/node-wav-stream.

Keep in mind that handling data like this will result in issues because using this code, there is only one FileWriter stream variable for every client that connects. You should create an array for each client stream and use client session ID's to store and identify each stream item that belongs to the corresponding client.

发布评论

评论列表(0)

  1. 暂无评论