Skip to content Skip to sidebar Skip to footer

Html5 Audio Object Doesn't Play On Ipad (when Called From A Settimeout)

I have a page with a hidden

Solution 1:

See Apple's iOS considerations guide:

...the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad="play()" event does not.

It appears that your setTimeout() callback does not qualify as user-initiated action, despite the fact that the setTimeout() itself was in a user-initiated function.

Suggestion: I don't have an iOS device to test on, but maybe doing an initial play/pause when the user presses the button will relieve this restriction. That is, you call play() and then pause it at once, then make your call to animate and the setTimeout() function with the play() call. This makes the user-initiated function let iOS know that it is okay to load and play this video in the future.

Solution 2:

Some devices you cant automate the call to play Audio system have you tried using a button and clicking play see if that works if so how does it work does it open an audio player to play it if so your not allowed to automatic play the media this is the same as the Video tag if I remember correctly

I think safari checks for an event to fire the audio Hence why clicking works

Solution 3:

@apsillers suggests in his answer that I could rearrange my code to fulfil the iPad's 'user-initiated action' requirement. I've done some digging and this turns out to be true.

The requirement seems to be that the play() call may only be within onesetTimeout (Hence, the simplified example I gave in the original question does work — I originally had play() several setTimeouts deep).

So this will work:

constructor: (@_button, @_audio) ->
  @_button.on'click', @_play_play: (e) =>setTimeout (=>
    @_audio[0].play()                  // play() is only inside one setTimeout
  ), 300

And this would also work:

constructor: (@_button, @_audio) ->
  @_button.on'click', =>
    setTimeout ((e) =>@_play(e)
    ), 300_play: (e) =>@_audio[0].play()                    // Still only inside one setTimeout

But this will not work:

constructor: (@_button, @_audio) ->
  @_button.on'click', @_play_play: (e) =>setTimeout (=>
    // Something usefulsetTimeout (=>
      @_audio[0].play()                // play() is inside two setTimeouts
    ), 300
  ), 300

Nor will this (my original setup):

constructor: (@_button, @_audio) ->
  @_button.on'click', @_play_play: (e) =>@_button
    .animate { prop: value }, 300, =>

      setTimeout (=>
        @_audio[0].play()              // play() still 'too deep'
      ), 300

In the last example, it seems that jQuery's animate callback is called from another setTimeout internal to the library so play() is again 'too deep'.

Post a Comment for "Html5 Audio Object Doesn't Play On Ipad (when Called From A Settimeout)"