Safari 11对HTML5音频的新自动播放限制

vng*_*lst 13 javascript safari ios html5-audio

我正在试图弄清楚Safari 11的(和iOS')自动播放限制是如何实现的,我不明白为什么以下内容不会开始播放音频文件:

/*
    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()
    })
}
Run Code Online (Sandbox Code Playgroud)
<div id='root'/>
Run Code Online (Sandbox Code Playgroud)

Safari适用于以下情况:

/*
    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()
  })
}
Run Code Online (Sandbox Code Playgroud)
<div id='root'/>
Run Code Online (Sandbox Code Playgroud)

有谁知道Safari如何判断某些东西是否是自动播放?我不是在寻找一种解决方法(例如,启动和暂停帮助),但我正在试图弄清楚它是如何工作的.

(有关Safari新的自动播放政策的更多背景信息,请访问:https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/)

小智 0

自动播放

audio.autoplay = true;
Run Code Online (Sandbox Code Playgroud)

请注意,对于移动设备,W3C 已指定用户必须触发播放以避免移动数据费用。

因此,对于移动设备,您需要向用户提供触发自动播放的按钮。

audio.autoplay = true;
Run Code Online (Sandbox Code Playgroud)
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.autoplay = true;
// 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();
  })
}
Run Code Online (Sandbox Code Playgroud)