Update: This is now necessary for Chrome, too. You might see this message in the console:
The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.
I've had much frustration dealing with Web Audio in Safari. Especially with ScriptProcessorNode
, it just doesn't want to work. Here's a solution I've arrived at. This is written in ES6 JavaScript, and will work in Safari (iOS and macOS) and Chrome:
function unlockAudioContext(audioCtx) { if (context.state !== 'suspended') return; const b = document.body; const events = ['touchstart','touchend', 'mousedown','keydown']; events.forEach(e => b.addEventListener(e, unlock, false)); function unlock() { audioCtx.resume().then(clean); } function clean() { events.forEach(e => b.removeEventListener(e, unlock)); } }
Call the function immediately after creating the audio context, like this:
const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); unlockAudioContext(audioCtx);
Here's something very similar in ES5:
function unlockAudioContext(audioCtx) { if (audioCtx.state === 'suspended') { var events = ['touchstart', 'touchend', 'mousedown', 'keydown']; var unlock = function unlock() { events.forEach(function (event) { document.body.removeEventListener(event, unlock) }); audioCtx.resume(); }; events.forEach(function (event) { document.body.addEventListener(event, unlock, false) }); } }
Leave a Reply