Reputation: 1747
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?
Upvotes: 5
Views: 4562
Reputation: 37308
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.
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
});
});
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);
}
});
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.com/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.
Upvotes: 6