JSFiddle - React, Tailwind, and code Playground
by juberti
HTML
<button id="playButton"
onclick="play()">
â–¶
</button>
<button id="stopButton"
onclick="stop()"
disabled>
Stop
</button>
<br><br>
<button id="stopTheNoiseButton"
onclick="stopTheNoise()">
If it gets annoying press this button
<audio>
JavaScript
const playButton = document.querySelector('#playButton');
const stopButton = document.querySelector('#stopButton');
const audioElement = document.querySelector('audio');
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
let mediaStreamDstNode = null;
let bufferSource = null;
function createBufferSource() {
const frameCount = 48000; // 1.0s at 48 kHz.
const channelCount = 2;
const buffer = audioCtx.createBuffer(channelCount, frameCount, audioCtx.sampleRate);
for (let channel = 0; channel < channelCount; channel++) {
const channelData = buffer.getChannelData(channel);
for (let i = 0; i < frameCount; i++) {
// Random values on [-0.1, 0.1].
channelData[i] = Math.random() * 0.2 - 0.1;
}
}
const source = audioCtx.createBufferSource();
source.buffer = buffer;
// Wire up source all the way to the output.
mediaStreamDstNode = mediaStreamDstNode || audioCtx.createMediaStreamDestination();
audioElement.srcObject = mediaStreamDstNode.stream;
source.connect(mediaStreamDstNode);
return source;
}
function play() {
bufferSource = createBufferSource();
bufferSource.onended = () => {
stop();
}
audioElement.play();
bufferSource.start();
playButton.setAttribute('disabled', true);
stopButton.removeAttribute('disabled');
}
function stop() {
if (!bufferSource) { return; }
bufferSource.stop();
bufferSource.disconnect();
bufferSource = null;
// After 1 sec, Safari iOS 14 produces noise unless either:
// audioElement.srcObject = null;
// audioElement.pause();
//
// But these steps shouldn't be needed.
// We've already stopped and disconnected bufferSource.
//
// In contrast, the following browsers work fine:
// Safari 13.1.2 (MacOS)
// Chrome 85
playButton.removeAttribute('disabled');
stopButton.setAttribute('disabled', true);
}
function stopTheNoise() {
audioElement.srcObject = null;
}