I'm trying to make fade in / fade out effects using a given HTMLAudio element. To use Web Audio API's AudioParam interface for that purpose, I wrapped the HTMLAudio element around a MediaElementSource node and connect it to a Gain node. The following code works perfectly in desktop Chrome browser. However, it doesn't work in Android Chrome. (the sound doesn't diminish but stops abruptly after 2 seconds.)
<!DOCTYPE html>
<body>
<button disabled>Play</button>
<script>
var button = document.getElementsByTagName('button')[0];
var audioElem = new Audio();
audioElem.src = 'bgm.mp3';
var ctx = new AudioContext();
var sourceNode = ctx.createMediaElementSource(audioElem);
var gainNode = ctx.createGain();
sourceNode.connect(gainNode);
gainNode.connect(ctx.destination);
audioElem.addEventListener('canplay', function () {
button.disabled = false;
}, false);
button.addEventListener('click', function () {
if (button.textContent === 'Play') {
// Fade in
audioElem.play();
fade(0, 1, 2)
.then(function () {
button.textContent = 'Pause';
button.disabled = false;
});
} else {
// Fade out
fade(1, 0, 2)
.then(function () {
audioElem.pause();
button.textContent = 'Play';
button.disabled = false;
});
}
button.disabled = true;
}, false);
function fade(start, end, duration) {
return new Promise(function (pFulfill, pReject) {
// Fade in/out using AudioParam interface.
gainNode.gain.linearRampToValueAtTime(start, ctx.currentTime);
gainNode.gain.linearRampToValueAtTime(end, ctx.currentTime + duration);
setTimeout(function () {
pFulfill();
}, duration * 1000);
});
}
</script>
</body>
Does anyone know any workarounds?