Skip to content

Instantly share code, notes, and snippets.

@westc
Last active July 15, 2018 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westc/6fcb34757dc15580b32cf955d6763869 to your computer and use it in GitHub Desktop.
Save westc/6fcb34757dc15580b32cf955d6763869 to your computer and use it in GitHub Desktop.
Prototype to easily set the volume (actual and perceived), loudness, decibels, and gain value of <audio> tags and <video> tags.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Example Page</title>
<script src="MediaElementAmplifier.js"></script>
<script type="text/JavaScript">
document.addEventListener("DOMContentLoaded", function(event) {
var amp = new MediaElementAmplifier(document.getElementById('testVideo'));
amp.setLoudness(2); // Sets the video to be twice as loud as normal
});
</script>
</head>
<body>
<h1>Example Page</h1>
<video id="testVideo" src="example.mp4" autoplay poster="posterimage.jpg">
Your browser does not support embedded videos. You can alternatively
<a href="example.mp4">download it</a> and watch it.
</video>
</body>
</html>
/**
* @license Copyright 2017 - Chris West - MIT Licensed
* Prototype to easily set the volume (actual and perceived), loudness,
* decibels, and gain value.
*/
function MediaElementAmplifier(mediaElem) {
this._context = new (window.AudioContext || window.webkitAudioContext);
this._source = this._context.createMediaElementSource(this._element = mediaElem);
this._source.connect(this._gain = this._context.createGain());
this._gain.connect(this._context.destination);
}
[
'getContext',
'getSource',
'getGain',
'getElement',
[
'getVolume',
function(opt_getPerceived) {
return (opt_getPerceived ? this.getLoudness() : 1) * this._element.volume;
}
],
[
'setVolume',
function(value, opt_setPerceived) {
var volume = value / (opt_setPerceived ? this.getLoudness() : 1);
if (volume > 1) {
this.setLoudness(this.getLoudness() * volume);
volume = 1;
}
this._element.volume = volume;
}
],
[ 'getGainValue', function() { return this._gain.gain.value; } ],
[ 'setGainValue', function(value) { this._gain.gain.value = value; } ],
[ 'getDecibels', function() { return 20 * Math.log10(this.getGainValue()); } ],
[ 'setDecibels', function(value) { this.setGainValue(Math.pow(10, value / 20)); } ],
[ 'getLoudness', function() { return Math.pow(2, this.getDecibels() / 10); } ],
[ 'setLoudness', function(value) { this.setDecibels(10 * Math.log2(value)); } ]
].forEach(function(name, fn) {
if ('string' == typeof name) {
fn = function() { return this[name.replace('get', '').toLowerCase()]; };
}
else {
fn = name[1];
name = name[0];
}
MediaElementAmplifier.prototype[name] = fn;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment