Question

Chrome for Android versions 30 and 31 beta on Android 4.1 do not appear to correctly record audio using HTML5 web audio and navigator.webkitGetUserMedia. (Chrome 30+ on Android is supposed to support these APIs.)

The symptom is that the code appears to work correctly, including displaying the prompt for whether or not to allow microphone access, but recorded data contains nothing but zeros.

I created a simplified testcase (go to http://jsfiddle.net/JCFtK/, and click Record button, then choose the appropriate option to allow it to access your microphone). The key part of the code is below ('record' function is the entry point).

function processAudioBuffer(e) {
    var floats = e.inputBuffer.getChannelData(0);
    var min = 0, max = 0;
    for (var i = 0; i < floats.length; i++) {
        var current = floats[i];
        min = Math.min(current, min);
        max = Math.max(current, max);
    }
    log('Block min/max: ' + min.toFixed(3) + ', ' + max.toFixed(3));
}

function record() {
    if (!window.AudioContext) {
        window.AudioContext = window.webkitAudioContext;
    }
    if (!navigator.getUserMedia) {
        navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
    }
    data.context = new AudioContext();
    navigator.getUserMedia({audio: true}, function(stream) {
        data.mediaStream = stream;
        startAudio();
    }, function(error) {
        log('Stream get error: ' + error);
    });
}

function startAudio() {
    // Get input media stream.
    data.audioStream = data.context.createMediaStreamSource(data.mediaStream);

    // Set up JS processor.
    data.processor = data.context.createScriptProcessor(2048, 1, 1);
    data.processor.onaudioprocess = processAudioBuffer;

    // You need to connect the output of processor to the audio output or it
    // doesn't work. (In Firefox, connecting it just to a gain node works;
    // in Chrome you have to connect to output like this.)
    data.processor.connect(data.context.destination);

    // Connect input stream to processor, then we're done.
    data.audioStream.connect(data.processor);
    log('Stream connected OK');
}

The test shows the min/max audio value from each recorded block. When it is working - as it does in desktop Chrome, for instance - you'll see the min/max values vary depending on background noise. When it is not working, these values are always 0.000.

This testcase WORKS in the following:

  • Chrome 30 (Windows)
  • Firefox 25 (Windows)
  • Firefox 25 (Android 4.1) on a Sony Xperia M
  • Firefox 25 (Android 4.1) on a Samsung tablet

This test case DOES NOT WORK in the following:

  • Chrome 30 (Android 4.1) on a Sony Xperia M
  • Chrome beta 31 (Android 4.1) on a Sony Xperia M
  • Chrome 30 (Android 4.1) on a Samsung tablet

The testcase also doesn't work in other browsers such as Safari or IE, but that's expected as they do not support the necessary APIs. It's only Chrome for Android that I was hoping to make this work on, but it doesn't.

I've filed this as an issue using the Chrome issue reporting process (which is private and possibly a black hole) but I thought I'd also ask here: is anyone aware of workarounds that would fix this code so I can actually make it work on Chrome for Android?

(A requirement for my purposes is that the recorded audio must go to a JavaScript event handler such as the one here, and e.g. not directly to the server as part of a form upload, which very possibly might work already.)

I get the impression that this is bleeding-edge stuff and not too many people are trying to use it, but I thought it might be worth asking. :)

Was it helpful?

Solution

We're still working on audio input in Android; it's enabled in version 31, but it's not turned on across all devices yet. It does work on Nexus devices, at least - N4, N5, N7.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top