Skip to content

Instantly share code, notes, and snippets.

@kus
Last active August 3, 2024 09:58
Show Gist options
  • Save kus/3f01d60569eeadefe3a1 to your computer and use it in GitHub Desktop.
Save kus/3f01d60569eeadefe3a1 to your computer and use it in GitHub Desktop.
Fix iOS AudioContext on Safari not playing any audio. It needs to be "warmed up" from a user interaction, then you can play audio with it as normal throughout the rest of the life cycle of the page.
// Fix iOS Audio Context by Blake Kus https://gist.github.com/kus/3f01d60569eeadefe3a1
// MIT license
(function() {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
if (window.AudioContext) {
window.audioContext = new window.AudioContext();
}
var fixAudioContext = function (e) {
if (window.audioContext) {
// Create empty buffer
var buffer = window.audioContext.createBuffer(1, 1, 22050);
var source = window.audioContext.createBufferSource();
source.buffer = buffer;
// Connect to output (speakers)
source.connect(window.audioContext.destination);
// Play sound
if (source.start) {
source.start(0);
} else if (source.play) {
source.play(0);
} else if (source.noteOn) {
source.noteOn(0);
}
}
// Remove events
document.removeEventListener('touchstart', fixAudioContext);
document.removeEventListener('touchend', fixAudioContext);
};
// iOS 6-8
document.addEventListener('touchstart', fixAudioContext);
// iOS 9
document.addEventListener('touchend', fixAudioContext);
})();
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Fix iOS Audio Context</title>
<meta name="author" content="Blake Kus">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>iOS Safari AudioContext Demo</h1>
<p>Load on iOS device without touching the screen and it will not play a noise after 3 seconds.</p>
<p>Refresh the page touch the screen (within 3 seconds of it loading) and the audio and any other audio will play outside of a user generated event.</p>
<p id="status">Waiting 3 seconds to play audio...</p>
<script type="text/javascript">
// Fix iOS Audio Context by Blake Kus https://gist.github.com/kus/3f01d60569eeadefe3a1
// MIT license
(function() {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
if (window.AudioContext) {
window.audioContext = new window.AudioContext();
}
var fixAudioContext = function (e) {
if (window.audioContext) {
// Create empty buffer
var buffer = window.audioContext.createBuffer(1, 1, 22050);
var source = window.audioContext.createBufferSource();
source.buffer = buffer;
// Connect to output (speakers)
source.connect(window.audioContext.destination);
// Play sound
if (source.start) {
source.start(0);
} else if (source.play) {
source.play(0);
} else if (source.noteOn) {
source.noteOn(0);
}
}
// Remove events
document.removeEventListener('touchstart', fixAudioContext);
document.removeEventListener('touchend', fixAudioContext);
};
// iOS 6-8
document.addEventListener('touchstart', fixAudioContext);
// iOS 9
document.addEventListener('touchend', fixAudioContext);
})();
var $status = document.querySelector('#status');
function playSound () {
var path = '../sounds/laser.mp3';
var context = window.audioContext;
var request = new XMLHttpRequest();
$status.innerHTML = 'Playing ' + path;
request.open('GET', path, true);
request.responseType = 'arraybuffer';
request.addEventListener('load', function (e) {
context.decodeAudioData(this.response, function (buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
});
}, false);
request.send();
}
setTimeout(playSound, 3000);
</script>
</body>
</html>
@RobertSwirsky
Copy link

RobertSwirsky commented Nov 3, 2016

I just tried this, copying your example exactly, except for putting my own sample audio file, and it doesn't work on iPad an iPhone. No errors, and the server did serve the audio file to the application. Works fine as-is on desktop Safari and Chrome; doesn't play anything on firefox.

I refresh and pressed the screen within 3 seconds. I tried adding a button just to have something to press, and that didn't help.

Did Apple change something recently?

I put it up here so you can see for yourself:

http://side.band/audio

@frixo3190
Copy link

me too, nothing work on iphone, but work on mac, and pc and android

@1312543912
Copy link

me too.........mac safari and ios safari not work

@kuboon
Copy link

kuboon commented Nov 24, 2021

just resume like this:

document.addEventListener('touchend', ()=>window.audioContext.resume());

@alexandrebaux
Copy link

@kuboon

Works like a charm!

@alexcraviotto
Copy link

me too, nothing work on iphone, but work on mac, and pc and android

Did you fix that? I'm dealing with this exactly

@Alex-Li2018
Copy link

me too

@kuboon
Copy link

kuboon commented Mar 27, 2024

@alexcraviotto @Alex-Li2018 Did you try my solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment