Shih-En Chou
Shih-En Chou

Reputation: 4185

Record Audio Stream from getUserMedia

In recent days, I tried to use javascript to record audio stream. I found that there is no example code which works.

Is there any browser supporting?

Here is my code

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia || navigator.msGetUserMedia; 

navigator.getUserMedia({ audio: true }, gotStream, null);
function gotStream(stream) {

        msgStream = stream;        
        msgStreamRecorder = stream.record(); // no method record :(
}

Upvotes: 13

Views: 25583

Answers (5)

jrullmann
jrullmann

Reputation: 2978

getUserMedia gives you access to the device, but it is up to you to record the audio. To do that, you'll want to 'listen' to the device, building a buffer of the data. Then when you stop listening to the device, you can format that data as a WAV file (or any other format). Once formatted you can upload it to your server, S3, or play it directly in the browser.

To listen to the data in a way that is useful for building your buffer, you will need a ScriptProcessorNode. A ScriptProcessorNode basically sits between the input (microphone) and the output (speakers), and gives you a chance to manipulate the audio data as it streams. Unfortunately the implementation is not straightforward.

You'll need:

  • getUserMedia to access the device
  • AudioContext to create a MediaStreamAudioSourceNode and a ScriptProcessorNode
  • MediaStreamAudioSourceNode to represent the audio stream
  • ScriptProcessorNode to get access to the streaming audio data via an onaudioprocessevent. The event exposes the channel data that you'll build your buffer with.

Putting it all together:

navigator.getUserMedia({audio: true},
  function(stream) {
    // create the MediaStreamAudioSourceNode
    var context = new AudioContext();
    var source = context.createMediaStreamSource(stream);
    var recLength = 0,
      recBuffersL = [],
      recBuffersR = [];

    // create a ScriptProcessorNode
    if(!context.createScriptProcessor){
       node = context.createJavaScriptNode(4096, 2, 2);
    } else {
       node = context.createScriptProcessor(4096, 2, 2);
    }

    // listen to the audio data, and record into the buffer
    node.onaudioprocess = function(e){
      recBuffersL.push(e.inputBuffer.getChannelData(0));
      recBuffersR.push(e.inputBuffer.getChannelData(1));
      recLength += e.inputBuffer.getChannelData(0).length;
    }

    // connect the ScriptProcessorNode with the input audio
    source.connect(node);
    // if the ScriptProcessorNode is not connected to an output the "onaudioprocess" event is not triggered in chrome
    node.connect(context.destination);
  },
  function(e) {
    // do something about errors
});

Rather than building all of this yourself I suggest you use the AudioRecorder code, which is awesome. It also handles writing the buffer to a WAV file. Here is a demo.

Here's another great resource.

Upvotes: 35

Mikael Holmgren
Mikael Holmgren

Reputation: 2526

You could check this site: https://webaudiodemos.appspot.com/AudioRecorder/index.html

It stores the audio into a file (.wav) on the client side.

Upvotes: 2

mido
mido

Reputation: 25054

for browsers that support MediaRecorder API, use it.

for older browsers that does not support MediaRecorder API, there are three ways to do it

  1. as wav
  2. as mp3
  3. as opus packets (can get output as wav, mp3 or ogg)

Upvotes: 7

Vidhuran
Vidhuran

Reputation: 222

Currently, this is not possible without sending the data over to the server side. However, this would soon become possible in the browser if they start supporting the MediaRecorder working draft.

Upvotes: -2

Todd
Todd

Reputation: 11

There is a bug that currently does not allow audio only. Please see http://code.google.com/p/chromium/issues/detail?id=112367

Upvotes: 1

Related Questions