6
votes

The navigator.getUserMedia(....) call can be used in some modern browser to record audio in Javascript.

Is there a way to adjust/set the input volume level of the microphone?

The setting for this is not always optimal. Sometimes the microphone is set to record only at a very very low input volume. Sure the user could adjust manually the input volume level in his system, but most of my users might lack the knowledge to do this. Therefore it would be best I could adjust the microphone volume dynamically inside of the very JavaScript application which records the data via the "navigator.getUserMedia(....)" way?

Are there solutions out there to influence this input volume level of the microphone?

1

1 Answers

9
votes

The Web Audio API enables you to change the input of the microphone for the stream.

Here is an example, which shows how to convert a MediaStream to another MediaStream, but with the ability to change the volume on the fly. If you just want to play back the audio, then you can change gainNode.connect(dest) to gainNode.connect(ctx.destination) and remove the two other lines that use the dest variable.

if (!navigator.getUserMedia) {
    navigator.getUserMedia = navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia;
}
navigator.getUserMedia({
    audio: true
}, function(stream) {
    var ctx = new AudioContext();
    var source = ctx.createMediaStreamSource(stream);
    var dest = ctx.createMediaStreamDestination();
    var gainNode = ctx.createGain();

    source.connect(gainNode);
    gainNode.connect(dest);
    document.getElementById('volume').onchange = function() {
        gainNode.gain.value = this.value; // Any number between 0 and 1.
    };
    gainNode.gain.value = document.getElementById('volume').value;
    
    // Example: play the audio
    // Or if you use WebRTC, use peerConnection.addStream(dest.stream);
    new Audio(URL.createObjectURL(dest.stream)).play();

    // Store the source and destination in a global variable
    // to avoid losing the audio to garbage collection.
    window.leakMyAudioNodes = [source, dest];
}, function(e) {
    alert(e); // TODO: Handle error.
});

// For the demo only:
document.getElementById('volume').onchange = function() {
    alert('Please provide access to the microhone before using this.');
};
Volume: <input type=range id=volume min=0 max=1 value=1 step=0.01>

Note: The live demo via Stack snippet does not work in Chrome because getUserMedia seems non-functional for sandboxed frames. If you use Chrome, try snippet at: https://robwu.nl/s/mediasource-change-volume.html