在微信及支付寶下的音訊自動播放
阿新 • • 發佈:2019-02-06
廢話不多說,直接上程式碼。
// 微信、支付寶音訊Hack方案 ; void function (win, doc, undefined) { // 原理:呼叫鏈中的某個事件被標識為使用者事件而非系統事件 // 進而導致瀏覽器以為是使用者觸發播放而允許播放 Audio.prototype._play = Audio.prototype.play; HTMLAudioElement.prototype._play = HTMLAudioElement.prototype.play; function wxPlay(audio) { /// <summary> /// 微信播放Hack /// </summary> /// <param name="audio" type="Audio">音訊物件</param> WeixinJSBridge.invoke('getNetworkType', {}, function (e) { audio._play(); }); } function alipayPlay(audio) { /// <summary> /// 支付寶播放Hack /// </summary> /// <param name="audio" type="Audio">音訊物件</param> AlipayJSBridge.call('getNetworkType', function (result) { audio._play(); }); } function play() { var self = this; self._play(); try { wxPlay(self); } catch (ex) { document.addEventListener("WeixinJSBridgeReady", function evt() { wxPlay(self); document.removeEventListener("WeixinJSBridgeReady", evt, false); }, false); } try { alipayPlay(self); } catch (ex) { document.addEventListener('AlipayJSBridgeReady', function evt() { alipayPlay(self); document.removeEventListener("AlipayJSBridgeReady", evt, false); }, false); } } Audio.prototype.play = play; HTMLAudioElement.prototype.play = play; }(window, document);
起因:
在IOS及Android中無法自動播放音訊(出於流量和使用者體驗的考慮,所以用JS直接呼叫play是無效的)。
但是產品狗們卻要求必須開啟頁面就播放聲音,這可難倒了很多人。
那麼我們首先要知道什麼情況下呼叫play函式是有效的,什麼時候是無效的。
var audio = new Audio("xxx.mp3");
audio.play(); // 無效
document.body.onclick = function(){
audio.play(); // 有效
};
從上面的程式碼中可以看出,只有使用者事件中觸發play函式才有效。
什麼是使用者事件?click事件、touch事件、mouse事件以及keyboard事件等必須使用者手動觸發的事件為使用者事件。
既然是使用者事件才會觸發,那我們有沒有辦法模擬一個使用者事件?
答案是肯定的,由於微信、支付寶有擴充套件API,而此類API是直接內嵌入Js中的,這時Js會把這些內容當成是使用者手動觸發的內容。
所以我們就可以利用這個來達到效果。
首先將原生的play函式儲存下來,然後重寫Audio以及HTMLAudioElement原型中的play函式。
接下來是重點,我們要呼叫一個不會產生任何影響的應用擴充套件函式,並在回撥函式中觸發play。
仔細看了一下微信以及支付寶中的介面,發現獲取網路資訊的介面最符合,因為即使失敗了也會呼叫回撥,而且沒有任何不良影響。
總結:
有時候解決問題的方法有很多,只要能解決問題的方法就是好方法。