不同瀏覽器下 autoplay 的限制策略和方案的整理

weixin_33806914發表於2019-02-25

不同瀏覽器下 autoplay 的限制策略和方案的整理

PC 端瀏覽器的限制策略 和 應對方案

使用 Mac 在 PC 端測試的瀏覽器包括

  • Chrome 瀏覽器
  • Safari 瀏覽器
  • Firefox 瀏覽器

Chrome 瀏覽器

Chrome-限制策略

內容參考自

2018 年 4 月份釋出的 Chrome 66 正式關掉了聲音自動播放

  • 靜音自動播放總是允許的。
  • 在下列情況下允許使用聲音自動播放:

    • 使用者已經與域進行了互動(點選,tap 等)。
    • 在桌面上,使用者的媒體參與指數閾值(MEI)已被越過,這意味著使用者以前播放帶有聲音的視訊。
    • 在移動裝置上,使用者已將該網站新增到主螢幕。
    • 頂部框架可以將自動播放許可權授予其 iframe 以允許自動播放聲音。

MEI 是一個評估使用者對於當前站點的媒體參與程度的指數,它取決於


-   使用者在媒體上停留時間超過了 7 秒以上
-   音訊必須是展示出來,並且沒有靜音
-   與 video 之間有過互動
-   媒體的尺寸不小於 200x140.
Chrome-應對方案
  • 1.不要假設視訊會播放,並且在視訊不是真正播放時不要顯示暫停按鈕。
  • 2.根據 promise 結果,判斷當前媒體是否支援 autoplay
var promise = document.querySelector("video").play();

if (promise !== undefined) {
    promise
        .catch(error => {
            // Auto-play was prevented
            // Show a UI element to let the user manually start playback
        })
        .then(() => {
            // Auto-play started
        });
}
  • 3.如果不支援,有 3 個選擇,

    • (1)靜音自動播放,
    • (2)或者選擇彈出 dialog 引導使用者產生一次互動,在 event 回撥裡呼叫 play()
    • (3)提高 Chrome 瀏覽器的 MEI 指數

Safari 瀏覽器

Safari 的限制策略和應對方案

內容參考自
https://webkit.org/blog/7734/...

Safari 瀏覽器使用自動推理引擎來阻止絕大多數網站預設自動播放的媒體元素。

Safari11 允許使用者通過「此網站的設定」選項,讓使用者控制哪些網站可以自動播放音視訊

  • 1.判斷當前媒體是否支援 autoplay
  • 2.如果不支援,有 3 個選擇

    • 靜音自動播放
    • 引導使用者對瀏覽器設定為【允許自動播放】
    • 彈出 dialog 引導使用者產生一次互動,在 event 回撥裡呼叫 play()

靜音自動播放例子:

clipboard.png

彈出 dialog 引導使用者產生一次互動的例子:
clipboard.png

引導使用者對瀏覽器設定為【允許自動播放】的例子:

clipboard.png

clipboard.png

Firefox 瀏覽器

個人測試的結果是 Firefox 瀏覽器支援 autoplay

移動端瀏覽器的限制策略 和 應對方案

使用 Android 手機測試的瀏覽器包括以下

  • Firefox / QQ 瀏覽器 / 釘釘
  • 微信
  • Chrome
  • Safari
  • UC瀏覽器

其中 Firefox / QQ 瀏覽器 / 釘釘 使用 video autoplay 的表現良好

微信的限制策略和應對方案

微信上實現自動播放需要用到一個 API WeixinJSBridge

它是在微信內建瀏覽器中有一個內建的 JS 物件,這個內建的 JS 物件就是 WeixinJSBridge. WeixinJSBridge 並不是 WebView 一開啟就有了,客戶端需要初始化這個物件,當這個物件準備好的時候,客戶端會丟擲事件 "WeixinJSBridgeReady"。因此,在呼叫 WeixinJSBridge 相關 api 時,需要做好 WeixinJSBridge 存在與否的判斷.

//監聽 WeixinJSBridge 是否存在
if (
    typeof WeixinJSBridge == "object" &&
    typeof WeixinJSBridge.invoke == "function"
) {
    vedio.play();
} else {
    //監聽客戶端丟擲事件"WeixinJSBridgeReady"
    if (document.addEventListener) {
        document.addEventListener(
            "WeixinJSBridgeReady",
            function() {
                vedio.play();
            },
            false
        );
    } else if (document.attachEvent) {
        document.attachEvent("WeixinJSBridgeReady", function() {
            vedio.play();
        });
        document.attachEvent("onWeixinJSBridgeReady", function() {
            vedio.play();
        });
    }
}
移動端 Chrome 的限制和解決方案
  • muted可以自動靜音播放
  • 引導使用者做一次互動可以播放
  • MEI值高的網站,可以自動播放
移動端 Safari 的限制和解決方案
  • muted可以自動靜音播放
  • 引導使用者做一次互動可以播放
  • 引導使用者對瀏覽器設定為【允許自動播放】
移動端 UC瀏覽器 的限制和解決方案
  • 靜音模式也無法自動播放
  • 彈出dialog,引導使用者做一次互動可以播放

音訊的限制策略和應對方案

參考資料

https://segmentfault.com/a/11...

音訊元素

原生播放音訊除了使用audio標籤之外,還有另外一個API叫AudioContext,AudioContext介面表示由音訊模組連線而成的音訊處理圖,每個模組對應一個AudioNode。AudioContext可以控制它所包含的節點的建立,以及音訊處理、解碼操作的執行。做任何事情之前都要先建立AudioContext物件,因為一切都發生在這個環境之中。

AudioContext播放聲音
  1. 先請求音訊檔案,放到ArrayBuffer裡面,然後用AudioContext的API進行decode解碼,解碼完了再讓它去play。
function request (url) {
    return new Promise (resolve => {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        // set response Type arraybuffer
        xhr.responseType = 'arraybuffer';
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                resolve(xhr.response);
            }
        };
        xhr.send();
    });
}
  1. 例項化AudioContext
// Safari是使用webkit字首
let context = new (window.AudioContext || window.webkitAudioContext)();
  1. 解碼播放
function play (context, decodeBuffer) {
    let source = context.createBufferSource();
    source.buffer = decodeBuffer;
    source.connect(context.destination);
    // 從0s開始播放
    source.start(0);
}
// 請求音訊資料
let audioMedia = await request(url);
// 進行decode和play
context.decodeAudioData(audioMedia, decode => play(context, decode));

相關文章