web-dev-qa-db-ja.com

Chrome / Safari / Firefoxがビデオの自動再生をブロックしたかどうかを検出するにはどうすればよいですか?

バックグラウンド

Chromeバージョン66以降、ユーザーが以前に自分のサイトにアクセスしたことがない場合、サイトで自動再生する必要がある動画は再生できない場合があります。

<video src="..." autoplay></video>

質問

ビデオの自動再生が無効にされたかどうかをどのように検出しますか?そして、私はそれについて何ができますか?

6
maxpaj

autoplay属性

Web標準仕様によれば、autoplay属性は、ブラウザがメディア要素に対して行うべきことのヒントのみである必要があります。 W のいずれでもない [〜#〜] whatwg [〜#〜] Web仕様は、メディアの自動再生をいつ禁止するかについて何も述べていない。つまり、各ブラウザーの実装はおそらく異なる。

自動再生ポリシー

各ブラウザによって実装される自動再生ポリシーは、ビデオの自動再生を許可するかどうかを制御するようになりました。

  • ChromeはMedia Engagement Indexと呼ばれるものを使用しており、その詳細については here と自動再生ポリシー here をご覧ください。
  • Safari開発者はこれに関して webkit.orgへの投稿 を作成しました。

  • Firefoxはそれを許可するかどうかをユーザーが選択できるようにしています( link )。

ベストプラクティス

このセクションでは、ベストプラクティスとは何か、何ができるかについて説明します。

自動再生が無効になっているかどうかの検出

エレメントでautoplayを使用する代わりに、videoおよびaudioエレメントでplay()メソッドを使用して、メディアの再生を開始できます。 play()メソッドは、最新のブラウザー(すべて仕様に準拠)でPromiseを返します。プロミスが拒否した場合は、サイトの現在のブラウザで自動再生が無効になっている可能性があります。

can-autoplay は、ビデオ要素とオーディオ要素の両方の自動再生機能を検出するためだけのライブラリです。

自動再生が無効になっている場合

自動再生が無効になっていることがわかっている場合は、一部のブラウザで動画をミュートしてplay()メソッドをもう一度試すことができ、UIで動画の再生中に、ミュート。

var video = document.querySelector('video');
var promise = video.play();

if (promise !== undefined) {
  promise.then(_ => {
    // Autoplay started!
  }).catch(error => {
    // Show something in the UI that the video is muted
    video.muted = true;
    video.play();
  });
}
<video src="https://www.w3schools.com/tags/movie.ogg" controls></video>
11
maxpaj

私にとって最高の解決策は:

function _callback_onAutoplayBlocked() {
    // do something, for example "show big play button"
}

function isSafari() {
    var chr = window.navigator.userAgent.toLowerCase().indexOf("chrome") > -1;
    var sfri = window.navigator.userAgent.toLowerCase().indexOf("safari") > -1;
    return !chr && sfri;
}

function _checkAutoPlay(p) {
    var s = window['Promise'] ? window['Promise'].toString() : '';

    if (s.indexOf('function Promise()') !== -1 || s.indexOf('function ZoneAwarePromise()') !== -1) {
        p.catch(function(error) {
            console.error("_checkAutoPlay, error:", error)
            if(error.name == "NotAllowedError") { // For Chrome/Firefox
                console.error("_checkAutoPlay: error.name:", "NotAllowedError")
                _callback_onAutoplayBlocked();
            } else if (error.name == "AbortError" && isSafari()) {  // Only for Safari
                console.error("_checkAutoPlay: AbortError (Safari)")
                _callback_onAutoplayBlocked();
            } else {
                console.error("_checkAutoPlay: happened something else ", error);
                // throw error; // happened something else
            }
        }).then(function(){
            console.log("_checkAutoPlay: then");
            // Auto-play started
        });
    } else {
        console.error("_checkAutoplay: promise could not work in your browser ", p);
    }
}

var video1 = document.getElementById('video1');
_checkAutoPlay(video1.play());
1
sea-kg