HTML5音频对象无法在iPad上播放(从setTimeout调用时)

Dan*_*day 5 javascript audio html5 settimeout ipad

我有一个隐藏<audio>对象的页面,通过javascript使用自定义按钮启动和停止.(原因是我想自定义按钮,而绘制音频播放器似乎会破坏iPad上的渲染性能).一个简化的例子(在coffeescript中):

// Works fine on all browsers

constructor: (@_button, @_audio) ->
  @_button.on 'click', @_play          // Bind button's click event with jQuery

_play: (e) =>
  @_audio[0].play()                    // Call play() on audio element
Run Code Online (Sandbox Code Playgroud)

从绑定到click事件的函数触发时,音频播放效果很好,但实际上我希望在播放文件之前完成动画,所以我放入.play()了一个setTimeout.但是,我无法让这个工作:

// Will not play on iPad

constructor: (@_button, @_audio) ->
  @_button.on 'click', @_play          // Bind button's click event with jQuery

_play: (e) =>
  setTimeout (=>                       // Declare a 300ms timeout
    @_audio[0].play()                  // Call play() on audio element
  ), 300
Run Code Online (Sandbox Code Playgroud)

我已经检查过@_audio(this._audio)是否在范围内,并且它的play()方法存在.为什么这不适用于iPad?

编辑:实际上,上面的简化测试用例确实有效.请参阅下面的@apsillers的回答以及我对它的评论.

aps*_*ers 11

请参阅Apple的iOS考虑因素指南:

... 除非用户操作触发或方法,否则JavaScript play()load()方法在用户启动播放之前也处于非活动状态.换句话说,用户启动的播放按钮有效,但事件却没有.play()load()onLoad="play()"

setTimeout()尽管事实上它setTimeout()本身是在用户启动的功能中,但您的回调似乎不符合用户启动的操作.

建议:我没有要测试的iOS设备,但是当用户按下按钮时可能正在进行初始播放/暂停将减轻此限制.也就是说,您调用play()然后立即暂停它,然后通过调用调用动画和setTimeout()函数play().这使得用户启动的功能让iOS知道将来加载和播放此视频是可以的.