Juanvulcano Juanvulcano - 1 year ago 53
Javascript Question

MediaRecorderAPI - Autorecord

I am currently trying to simulate audio autorecording. User speaks, and after he stops then audio should be submitted to the backend.
I already have a sample script that submits audio with start and stop click functions.

I'm trying to get sometype of value such as Amplitude, Volume or maybe a Threshold but I'm not sure if MediaRecorder supports this or if I need to look at Web Audio API or other solutions.

Can I achieve this with MediaRecorder?

Answer Source

Regarding the audio analysis of the mic input, the following example shows you how to take the audio captured by the mic, create an analyzer with createAnalyser method of the webkitAudioContext, connect the stream to the analyzer and calculate the FFT of the specified size, in order to calculate pitch and display the output sound wave.

window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = null;
var isPlaying = false;
var sourceNode = null;
var analyser = null;
var theBuffer = null;
var audioCtx = null;
var mediaStreamSource = null;
var rafID = null;
var j = 0;
var waveCanvas = null;

window.onload = function() {
    audioContext = new AudioContext();
    audioCtx = document.getElementById( "waveform" );
    canvasCtx = audioCtx.getContext("2d");
};
function getUserMedia(dictionary, callback) {
    try {
        navigator.getUserMedia = 
            navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia;
        navigator.getUserMedia(dictionary, callback, error);
    } catch (e) {
        alert('getUserMedia threw exception :' + e);
    }
}

function gotStream(stream) {
    // Create an AudioNode from the stream.
    mediaStreamSource = audioContext.createMediaStreamSource(stream);
    // Connect it to the destination.
    analyser = audioContext.createAnalyser();
    analyser.fftSize = 1024;
    mediaStreamSource.connect( analyser );
    updatePitch();
}
function toggleLiveInput() 
{
    canvasCtx.clearRect(0, 0, audioCtx.width, audioCtx.height);
    canvasCtx.beginPath();
    j = 0;
    buflen = 1024;
    buf = new Float32Array( buflen );
    document.getElementById('toggleLiveInput').disabled = true;
    document.getElementById('toggleLiveInputStop').disabled = false;
    if (isPlaying) {
        //stop playing and return
        sourceNode.stop( 0 );
        sourceNode = null;
        //analyser = null;
        isPlaying = false;
        if (!window.cancelAnimationFrame)
            window.cancelAnimationFrame = window.webkitCancelAnimationFrame;
        window.cancelAnimationFrame( rafID );
    }
    getUserMedia(
        {
            "audio": {
                "mandatory": {
                    "googEchoCancellation": "false",
                    "googAutoGainControl": "false",
                    "googNoiseSuppression": "false",
                    "googHighpassFilter": "false"
                },
                "optional": []
            },
        }, gotStream);
}
function stop()
{
    document.getElementById('toggleLiveInput').disabled = false;
    document.getElementById('toggleLiveInputStop').disabled = true;
    //waveCanvas.closePath();
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = window.webkitCancelAnimationFrame;
    window.cancelAnimationFrame( rafID );
    return "start";
}
function updatePitch() 
{
    analyser.fftSize = 1024;
    analyser.getFloatTimeDomainData(buf);
    canvasCtx.strokeStyle = "red";
    for (var i=0;i<2;i+=2) 
    {
        x = j*5;
        if(audioCtx.width < x)
        {
            x = audioCtx.width - 5;     
            previousImage = canvasCtx.getImageData(5, 0, audioCtx.width, audioCtx.height);
            canvasCtx.putImageData(previousImage, 0, 0);
            canvasCtx.beginPath();
            canvasCtx.lineWidth = 2;
            canvasCtx.strokeStyle = "red";
            prex = prex - 5;
            canvasCtx.lineTo(prex,prey);
            prex = x;
            prey = 128+(buf[i]*128);
            canvasCtx.lineTo(x,128+(buf[i]*128));
            canvasCtx.stroke();

        }
        else
        {
            prex = x;
            prey = 128+(buf[i]*128);
            canvasCtx.lineWidth = 2;
            canvasCtx.lineTo(x,128+(buf[i]*128));
            canvasCtx.stroke();
        }
        j++;
    }
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = window.webkitRequestAnimationFrame;
    rafID = window.requestAnimationFrame( updatePitch );
}
function error() {
    console.error(new Error('error while generating audio'));
}

Try the demo here. Example adapted from pitch-liveinput.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download