Controlling the Volume of an Audio File in Javascript

Just another quick tip. I’ll show you how to change the volume of an audio file of whatever format you are using – mp3, ogg, wav, aac, etc.

When Using the HTML5 <audio> Element

If you are using the audio tags, just get the DOM Node in Javascript and manipulate the volume property.

var audio = document.querySelector('audio');
// Getting
console.log(volume); // 1
// Setting
audio.volume = 0.5; // Reduce the Volume by Half

The number that you set should be in the range 0.0 to 1.0, where 0.0 is the quietest and 1.0 is the loudest.

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

Note: If the value you set is not in the range 0.0 to 1.0, then JS will throw an IndexSizeError.

Web Audio API

A bit of code first, where we’ll load our music file and play it using the Web Audio API.

var ctx = new webkitAudioContext();

function loadMusic(url) {
  var req = new XMLHttpRequest();
  req.open('GET', url, true);
  req.responseType = 'arraybuffer';

  req.onload = function() {
    ctx.decodeAudioData(req.response, playSound);
  };

  req.send();
}

function playSound(buffer) {
  var src = ctx.createBufferSource();
  src.buffer = buffer;
  src.connect(ctx.destination);
  // Play now!
  src.noteOn(0);
}

So, we load the audio file using XHR2 and then decode that to PCM Audio Data. In playSound we create a Source, set its buffer to the AudioBuffer object and connect it to the Destination (Speakers, Headphones, etc.). After the connection we finally play it. The entire flow is something like this:

Source -> Destination

If we want to control the volume of the audio, we need to connect the Source to a GainNode which in turn will be conntected to the Destination. The flow will be like this then:

Source -> GainNode -> Destination

The code will be something like this:

function playSound(buffer) {
  var src = ctx.createBufferSource();
  src.buffer = buffer;

  var gain_node = ctx.createGainNode();
  src.connect(gain_node);

  // ATTENTION! We're connecting the gain_node (NOT the source)
  // to the destination
  gain_node.connect(ctx.destination);

  // Changing the Volume
  gain_node.gain.value = 1;

  src.noteOn(0);
}

Nice! The gain_node object has a property called gain which in turn has a property called value. Now, Controlling the volume is just a matter of changing the value of gain_node.gain.value. You can set a negative value (less than 0) or more than 1 if you’d like to. Higher values will not throw exceptions unlike the other case that we covered with the <audio> element.

Note: noteOn() has been changed to start() recently in the specs.

Using an Input Range Slider

Hell yeah! You can use an input[type="range"] for better controls and change the volume of the audio! Quite simple, as you can already imagine. Just attach an onchange event handler to the input range and alter the gain_node.gain.value.

document
  .querySelector('#input_range_id')
  .addEventListener('change', function() {

  gain_node.gain.value = this.value;

}, false);

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

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

2 thoughts on “Controlling the Volume of an Audio File in Javascript”

  1. The input slider isn’t working, do you put the final bit of code in the onchange event handler? I’ve tried making it a function but that didn’t work either.

    Thanks

    1. Sorry there was a slight mistake in the last piece of code. Instead of addEventListener I used some random method called attachEventHandler which doesn’t exists in JavaScript.

      So try out the new updated code. If you’re still stuck then create a test case.

Leave a Reply

Your email address will not be published. Required fields are marked *