6

<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

イベントにバインドされた関数からトリガーされるとオーディオは正常に再生されますが、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

@_audiothis._audio)がスコープ内にあり、そのplay()メソッドが存在することを確認しました。なぜこれがiPadで機能しないのですか?

編集:たまたま、上記の簡略化されたテストケースは実際に機能します。以下の@apsillersの回答とそれに関する私のコメントを参照してください。

4

3 に答える 3

13

AppleのiOSに関する考慮事項ガイドを参照してください。

...またはメソッドがユーザーアクションによってトリガーされない限り、JavaScriptplay()load()メソッドは、ユーザーが再生を開始するまで非アクティブになります。つまり、ユーザーが開始した[再生]ボタンは機能しますが、イベントは機能しません。play()load()onLoad="play()"

コールバック自体がユーザーによって開始された関数内にあったsetTimeout()にもかかわらず、コールバックはユーザーによって開始されたアクションとして適格ではないようです。setTimeout()

提案:テストするiOSデバイスがありませんが、ユーザーがボタンを押したときに最初の再生/一時停止を行うと、この制限が緩和される可能性があります。つまり、呼び出しplay()から一度に一時停止してから、アニメーション化するための呼び出しと、呼び出しを伴う関数を作成します。これにより、ユーザーが開始した関数は、iOSに、将来このビデオをロードして再生しても問題がないことを通知します。setTimeout()play()

于 2012-06-11T16:13:50.937 に答える
1

オーディオシステムを再生するための呼び出しを自動化できない一部のデバイスでは、ボタンを使用して[再生]をクリックして、それが機能するかどうかを確認します。どのように機能するかを確認します。オーディオプレーヤーを開いて再生する場合は、メディアの自動再生が許可されていません。正しく覚えていれば、ビデオタグと同じです

サファリはオーディオを起動するイベントをチェックすると思いますそれでクリックが機能する理由

于 2012-06-11T16:11:56.170 に答える
1

@apsillersは彼の回答の中で、iPadの「ユーザーが開始するアクション」の要件を満たすようにコードを再配置できると示唆しています。私はいくつかの掘り下げを行いました、そしてこれは本当であることがわかりました。

要件は、呼び出しが1つplay()以内にしか収まらないことであるように思われます(したがって、元の質問で示した単純化された例は機能します—元々は数秒の深さでした)。 setTimeoutplay()setTimeout

したがって、これ機能します:

constructor: (@_button, @_audio) ->
  @_button.on 'click', @_play

_play: (e) =>
  setTimeout (=>
    @_audio[0].play()                  // play() is only inside one setTimeout
  ), 300

そして、これも機能します:

constructor: (@_button, @_audio) ->
  @_button.on 'click', =>
    setTimeout ((e) =>
      @_play(e)
    ), 300

_play: (e) =>
  @_audio[0].play()                    // Still only inside one setTimeout

しかし、これは機能しません:

constructor: (@_button, @_audio) ->
  @_button.on 'click', @_play

_play: (e) =>
  setTimeout (=>
    // Something useful
    setTimeout (=>
      @_audio[0].play()                // play() is inside two setTimeouts
    ), 300
  ), 300

これも(私の元の設定):

constructor: (@_button, @_audio) ->
  @_button.on 'click', @_play

_play: (e) =>

  @_button
    .animate { prop: value }, 300, =>

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

最後の例では、jQueryのアニメーションコールバックがsetTimeoutライブラリの内部にある別のコールバックから呼び出されているようplay()です。そのため、やはり「深すぎます」。

于 2012-06-11T17:08:02.563 に答える