I'm trying to figure out how Safari 11's (and iOS') autoplay restrictions are implemented and I don't understand why the following doesn't start playing the audio file:
/*
Call stack, this doesn't work 💩
*/
const btn = document.createElement('BUTTON')
const textLabel = document.createTextNode('Play')
const audio = new window.Audio()
audio.src = 'https://raw.githubusercontent.com/vnglst/autoplay-tutorial/master/mp3/winamp.mp3'
// audio.controls = true
btn.appendChild(textLabel)
document.getElementById('root').appendChild(btn)
document.getElementById('root').appendChild(audio)
btn.onclick = e => {
window
.fetch(`https://api.github.com/repos/vnglst/autoplay-tutorial/contents/mp3/modem-sound.mp3`)
.then(resp => resp.json())
.then(json => {
audio.src = json.download_url
audio.play()
})
}
<div id='root'/>
Whereas Safari is fine with the following:
/*
Call stack, using a fake Promise. This works 👍
*/
const btn = document.createElement('BUTTON')
const textLabel = document.createTextNode('Play')
const audio = new window.Audio()
audio.src = 'https://raw.githubusercontent.com/vnglst/autoplay-tutorial/master/mp3/modem-sound.mp3'
// audio.controls = true
btn.appendChild(textLabel)
document.getElementById('root').appendChild(btn)
document.getElementById('root').appendChild(audio)
const mockedPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const src = 'https://raw.githubusercontent.com/vnglst/autoplay-tutorial/master/mp3/winamp.mp3'
return resolve(src)
}, 500)
})
btn.onclick = (e) => {
mockedPromise.then(src => {
audio.src = src
audio.play()
})
}
<div id='root'/>
Does anybody know how Safari determines whether something is an autoplay or not? I'm not looking for a work around (starting and pausing helps for instance) but I'm trying to figure out how this works.
(some more background information on Safari's new autoplay policy can be found here: https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/)
In the Safari app on your Mac, choose Safari > Preferences, then click Websites. Click Auto-Play in the list on the left. Do any of the following: Choose settings for a website in the list: Select the website on the right, then choose the option you want for it.
In Safari, go to "Settings for This Website." Go to the right of Auto-Play, and click the pop-up menu to choose your preferred option: Allow All Auto-Play. Stop Media with Sound.
The HTML <audio> autoplay attribute is used to specify that the audio should automatically start playing as soon as it is loaded. It is a Boolean attribute.
You need to change your algorithm from
user clicks -> loads audio information -> changes source -> play
to
user clicks -> changes source -> play
Basically you need to change src
in audio
and start playback right after user clicks play button.
iOS prevents autoplay when intermediary fetching is present.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With