I'm building a simple voice chat app. I decide to use NodeJS, but I can't understand why buffers are always empty.
I'm using https://github.com/mattdiamond/Recorderjs
My code looks like this:
var audio_context;
var recorder;
function startUserMedia(stream) {
var input = audio_context.createMediaStreamSource(stream);
input.connect(audio_context.destination);
recorder = new Recorder(input);
}
function process() {
recorder.record();
setTimeout(function() {
recorder.getBuffer(function(data) {
console.log(data);
});
}, 3000);
}
window.onload = function init() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.URL = window.URL || window.webkitURL;
audio_context = new AudioContext;
} catch (e) {
console.log(e);
}
navigator.getUserMedia({audio: true}, startUserMedia);
setTimeout(process, 1500);
};
The problem is that when the getBuffer callback is executed data is always containing 2 empty arrays :(
I changed your code in
process
a little bit to make it easier to see what is going on.I also added one line to the beginning of
startUserMedia
:When you visit the page, Chrome should ask you to allow the use of your microphone. If you allow the microphone to be used before 'Entered process' prints in your console, everything should work correctly. You'll see the message 'Initializing' along with the Recorder object followed by 'Entered process'. Your arrays won't be empty, and a player should appear on the page allowing you to listen to the recording.
However, if 'Entered process' prints in the console before 'Initializing' (meaning you didn't allow the use of the microphone quickly enough), you will get back two empty arrays. Notice that
console.log(recorder)
now returns 'undefined' rather than the Recorder object.The function
startUserMedia
is a callback fornavigator.getUserMedia
, the function which tells the browser to prompt the user for permission to use a required media device (in this case your microphone). The callback is not executed until the user has given permission. The variablerecorder
is initialized instartUserMedia
, so we must wait for the user to give permission before we can use the Recorder object's API.process
, however, tries to record after a brief delay, regardless of whether or not permission has been given. This leads to the race condition described above.Edit: You can, of course, give yourself more time to react by increasing
setTimeout(process, 1500)
.Two last notes:
1. Make sure you are using Chrome!
2. I added the lines
recorder.stop()
andrecorder.clear()
toprocess
. Without these lines, you will find that the audio recorded when you first load the page is prepended to your next recording.