1. 程式人生 > >audio不能自動播放的解決方案

audio不能自動播放的解決方案

背景

實現H5改造客戶端版本的英語聽說答題功能,這裡涉及到很多頁面執行緒的使用,如果自動播放題目,每隔幾秒播放內容,迴圈播放幾次等等,在客戶端環境裡天生蘊藏著多執行緒操作和media的庫,而改成H5頁面的方式,只能好好研究H5的音訊播放控制的api。

audio嘗試

由於專案所給的時間非常緊,還沒有做好充分調研就開始磨刀霍霍,上來分析如果包裝題目資料,讓頁面播放題目的音訊更加的合理,根據題目的音訊數量按照一定的格式,比如audioPath、times、sleep等關鍵因素

  • audioPath:音訊的路徑,這裡包括專案本地路徑和遠端路徑的區分
  • times:迴圈幾次播放
  • sleep:播放完休眠多久,setInterval需要

憑藉自己前端的基礎,信心滿滿的噼裡啪啦胡亂的敲著鍵盤,宛如進入忘我的境地,縱有前方千軍萬馬,也要殺他個片甲不留。懷著這樣的心情程式碼大廈就被我一層一層的澆築成功,通過桌面瀏覽器按照想象的畫面勾勒出來,正所謂多情總被無情傷,整個過程我竟然忘我的用了平時個人衝浪的firefox瀏覽器,我怎麼沒用Chrome瀏覽器進行調測,真是不能原諒自己竟然犯了這個錯誤,firefox是支援audio進行自動播放,javascript進行api操控,完美達到預想中的效果,而Chrome和Safari 瀏覽器基於安全的策略,已經停止自動播放,主要現象如下:

  • Chrome提示:DOMException: play() failed because the user didn’t interact with the document first.
  • Safari 提示:NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.

一句話總結就是不允許你自動播放audio,即使你通過程式碼trigger觸發play等事件都是不允許的,必須要你進行和瀏覽器進行事件互動,人為的點選,觸控等操作才能播放。經調研得知:最開始移動端瀏覽器是完全禁止音視訊自動播放的,考慮到了手機的頻寬以及對電池的消耗。但是後來又改了,因為瀏覽器廠商發現網頁開發人員可能會使用 其他替代方案,而播放效能消耗更為糟糕,所以這樣對使用者反而是不利的。因此瀏覽器廠商放開了對多媒體自動播放的限制,只要具備以下條件就能自動播放:

  1. 沒音訊軌道,或者設定了 muted 屬性
  2. 在視圖裡面是可見的,要插入到 DOM 裡面並且不是 display: none 或者 visibility: hidden 的,沒有滑出可視區域

換句話說,只要你不開聲音擾民,且對使用者可見,就讓你自動播放,不需要你去使用 GIF 的方法進行 hack。這種實現主要對於視訊的,自動播放但是卻是靜音的,需要你點選喇叭才能有聲音,這對於音訊答題就跟沒說一樣。果斷放棄。。。。 而桌面瀏覽器Chrome官方提示2018.10月份也放開自動播放限制,不知道效果是不是和上面的一樣,如果一樣也是雞肋。

AudioContext

上天總是公平的,audio被閹割了,一定有另一個傢伙替代了他,而他就是AudioContext,可以自動播放,更多API可以參考MSDN,功能強大。

在這裡遇到了一個問題就是載入的音訊位元組陣列不可以跨域,而恰恰我的音訊檔案不是專案裡的地址。

let request = new XMLHttpRequest();
request.open("GET", link, true);
request.responseType = "arraybuffer";

解決跨域的問題無非就是那幾種方案,因為我當前的平臺就是跨域代理平臺,那就乾脆直接就通過代理的方式請求檔案流,返回給XMLHttpRequest吧,link直接只想後臺java邏輯

終於可以播放,幾大主流瀏覽器毫無壓力,不過還沒有上生產測試效果,而且併發起來之後我擔心讀取音訊流這塊會有瓶頸,不管怎麼樣,勝利的喜悅難以言表,應急的方案也很難完美。。。。。。。