Chrome下調(diào)用play后抱錯(cuò):DOMException: play() failed because the user didn't interact with the document first.
聲音無(wú)法自動(dòng)播放這個(gè)在IOS/Android上面一直是個(gè)慣例,桌面版的Safari在2017年的11版本也宣布禁掉帶有聲音的多媒體自動(dòng)播放功能,緊接著在2018年4月份發(fā)布的Chrome 66也正式關(guān)掉了聲音自動(dòng)播放,也就是說(shuō)
<audio autopaly></audio> <video autoplay></video>
在桌面版瀏覽器也將失效或悲。
最開(kāi)始移動(dòng)端瀏覽器是完全禁止音視頻自動(dòng)播放的,考慮到了手機(jī)的帶寬以及對(duì)電池的消耗郑象。但是后來(lái)又改了册烈,因?yàn)闉g覽器廠商發(fā)現(xiàn)網(wǎng)頁(yè)開(kāi)發(fā)人員可能會(huì)使用GIF動(dòng)態(tài)圖代替視頻實(shí)現(xiàn)自動(dòng)播放弥姻,正如IOS文檔所說(shuō)强经,使用GIF的帶寬流量是Video(h264)格式的12倍宵呛,而播放性能消耗是2倍,所以這樣對(duì)用戶反而是不利的夕凝。又或者是使用Canvas進(jìn)行hack宝穗,如Android Chrome文檔提到。因此瀏覽器廠商放開(kāi)了對(duì)多媒體自動(dòng)播放的限制码秉,只要具備以下條件就能自動(dòng)播放:
(1)沒(méi)音頻軌道逮矛,或者設(shè)置了muted屬性
(2)在視圖里面是可見(jiàn)的,要插入到DOM里面并且不是display: none或者visibility: hidden的转砖,沒(méi)有滑出可視區(qū)域须鼎。
換句話說(shuō),只要你不開(kāi)聲音擾民府蔗,且對(duì)用戶可見(jiàn)晋控,就讓你自動(dòng)播放,不需要你去使用GIF的方法進(jìn)行hack.桌面版的瀏覽器在近期也使用了這個(gè)策略
對(duì)于網(wǎng)頁(yè)開(kāi)發(fā)人員來(lái)說(shuō)姓赤,應(yīng)當(dāng)如何有效地規(guī)避這個(gè)風(fēng)險(xiǎn)呢赡译?
Chrome的文檔給了一個(gè)最佳實(shí)踐:先把音視頻加一個(gè)muted的屬性就可以自動(dòng)播放,然后再顯示一個(gè)聲音被關(guān)掉的按鈕不铆,提示用戶點(diǎn)一下打開(kāi)聲音蝌焚。對(duì)于視頻來(lái)說(shuō),確實(shí)可以這樣處理誓斥,而對(duì)于音頻來(lái)說(shuō)只洒,很多人是監(jiān)聽(tīng)頁(yè)面點(diǎn)擊事件,只要點(diǎn)一次了就開(kāi)始播放聲音劳坑,一般就是播放個(gè)背景音樂(lè)毕谴。但是如果對(duì)于有多個(gè)聲音資源的頁(yè)面來(lái)說(shuō)如何自動(dòng)播放多個(gè)聲音呢?
首先距芬,如果用戶還沒(méi)進(jìn)行交互就調(diào)用播放聲音的API涝开,Chrome會(huì)這么提示:
DOMException: play() failed because the user didn't interact with the document first.
Safari會(huì)這么提示:
NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Chrome報(bào)錯(cuò)提示最為友善,意思是說(shuō)蔑穴,用戶還沒(méi)有交互忠寻,不能調(diào)play。用戶的交互包括哪些呢存和?包括用戶觸發(fā)的touchend, click, doubleclick或者是 keydown事件奕剃,在這些事件里面就能調(diào)play.
所以上面提到很多人是監(jiān)聽(tīng)整個(gè)頁(yè)面的點(diǎn)擊事件進(jìn)行播放,不管點(diǎn)的哪里捐腿,只要點(diǎn)了就行纵朋,包括觸摸下滑。這種方法只適用于一個(gè)聲音資源茄袖,不適用多個(gè)聲音操软,多個(gè)聲音應(yīng)該怎么破呢?這里并不是說(shuō)要和瀏覽器對(duì)著干宪祥,“逆天而行”聂薪,我們的目的還是為了提升用戶體驗(yàn)家乘,因?yàn)橛行﹫?chǎng)景如果能自動(dòng)播放確實(shí)比較好,如一些答題的場(chǎng)景藏澳,需要聽(tīng)聲音進(jìn)行答題仁锯,如果用戶在答題的過(guò)程中能依次自動(dòng)播放相應(yīng)題目的聲音,確實(shí)比較方便翔悠。同時(shí)也是討論聲音播放的技術(shù)實(shí)現(xiàn)业崖。
原生播放視頻應(yīng)該就只能使用video標(biāo)簽,而原生播放音頻除了使用audio標(biāo)簽之外蓄愁,還有另外一個(gè)API叫AudioContext双炕,它是能夠用來(lái)控制聲音播放并帶了很多豐富的操控接口。調(diào)audio.play必須在點(diǎn)擊事件里面響應(yīng)撮抓,而使用AudioContext的區(qū)別在于只要用戶點(diǎn)過(guò)頁(yè)面任何一個(gè)地方之后就都能播放了妇斤。所以可以用AudioContext取代audio標(biāo)簽播放聲音。
對(duì)于移動(dòng)端開(kāi)發(fā)可考慮用原生AudioContext胀滚,使用參考:https://juejin.im/post/5af7129bf265da0b8262df4c
對(duì)于瀏覽器pc網(wǎng)頁(yè)可以不用這么麻煩趟济,設(shè)置了muted屬性就可以繞過(guò)去,解決方案就是默認(rèn)先加上muted標(biāo)簽咽笼,要播放的時(shí)候先關(guān)掉靜音顷编,再調(diào)用play方法播放就可以。