前言
也許很多前端遇到過這個需求:消息提醒。
一般來說,可以簡單的實現絕不會用複雜的方式,audio標籤提供了這個功能。
但是,新版的chrome瀏覽器禁止了js自動播放音頻的功能,見鬼了。
音頻播放
<audio src="../audio.mp3" id="myaudio" class="hide"></audio>
<script>
var audio = document.getElementById('myaudio');
audio.play();
</script>
這是最簡單的音頻播放腳本,但是在chrome下,拋出異常:Uncaught (in promise) DOMException
,原因是這種操作必須由用戶發起。當然,這不是特例,像F11全屏操作,瀏覽器也是禁止腳本操作的。
但是我們有這個需求,怎麼破?
絕不屈服的腦洞
能否不操作play呢?
chrome不僅禁止了腳本自動調用play,還禁止了audio的autoplay屬性。
但是,如果音頻是靜音狀態,autoplay屬性還是可以生效的。意思是,你可以播放,但是不能干擾用戶的視聽。
這就給我們提供了一個hack的方法:
默認開啓音頻的靜音播放,而且是循環播放,當我們需要提醒用戶的時候,把聲音打開,播放時間設置爲0秒,播放完畢,關掉聲音,繼續循環。
是的,音頻一直在播放,但是用戶聽不見。只有我們想讓用戶聽見的時候才能聽見,客觀上也能實現需求。
具體實現
<audio src="../audio.mp3" muted autoplay loop id="myaudio" style="display: none"></audio>
<script>
/*
* muted 靜音
* autoplay 自動播放
* loop 循環播放
*/
var audio = document.getElementById('myaudio');
var t1 = 3e3;//如果是輪詢,這個時間必須大於音頻的長度。如果是webscoket,應該設置一個狀態play,避免重複播放,如下:
var t2 = 2500;//音頻的長度,確保能夠完整的播放給用戶
var play = false;
funcrion run(){
if(play){
return false;
}
audio.currentTime = 0;//設置播放的音頻的起始時間
audio.volume = 0.5;//設置音頻的聲音大小
audio.muted = false;//關閉靜音狀態
play = true;
setTimeout(function(){
play = false;
audio.muted = true;//播放完畢,開啓靜音狀態
},t2);
}
setInterval(function(){
run();//假裝在輪詢服務器,或者從websocket拉取數據
},t1);
</script>
結語
這個方法經過在chrome上的實測,可以使用。
但是其他瀏覽器未做測試,據說有的瀏覽器,似乎是IE不支持muted屬性,限於操作系統,沒做測試,如果在IE運行有問題,可以給我提個醒。