Sometimes You only need a peak meter for some of the time that the page is loaded. For those cases, a peak meter instance can by dynamically created and cleaned up.
The web audio API context is loading.
<p>
The web audio API context is <span id="ctx-status">loading</span>.
<button id="ctx-button">Loading</button>
</p>
<audio id="the-audio" preload="metadata" crossorigin="anonymous" controls="controls">
<source src="https://assets.rpy.xyz/testmedia/semper_fidelis.mp3" type="audio/mpeg" />
</audio>
<div>
<button id="meter-toggle">Create meter</button>
</div>
<div id="peak-meter" style="height: 80px"></div>
const audioCtx = new AudioContext();
const audioElement = document.getElementById('the-audio');
const meterElement = document.getElementById('peak-meter');
const meterToggle = document.getElementById('meter-toggle');
const sourceNode = audioCtx.createMediaElementSource(audioElement);
sourceNode.connect(audioCtx.destination);
const ctxStatus = document.getElementById('ctx-status');
const buttonElement = document.getElementById('ctx-button');
function updateAudioCtxStatus() {
ctxStatus.innerText = audioCtx.state;
if (audioCtx.state === 'suspended') {
buttonElement.innerText = 'Resume';
} else {
buttonElement.innerText = 'Suspend';
}
}
setInterval(updateAudioCtxStatus, 1000);
buttonElement.addEventListener('click', () => {
if (audioCtx.state === 'suspended') {
audioCtx.resume().then(updateAudioCtxStatus);
} else {
audioCtx.suspend().then(updateAudioCtxStatus);
}
});
let meterInstance = null;
meterToggle.addEventListener('click', () => {
if (meterInstance) {
meterInstance.cleanup();
meterInstance = null;
meterToggle.innerText = 'Create meter';
} else {
meterInstance = new webAudioPeakMeter.WebAudioPeakMeter(sourceNode, meterElement);
meterToggle.innerText = 'Delete meter';
}
});