本文爲做者行舟客投稿,原文地址爲https://yunxiaomeng.blog.csdn.net/article/details/108672415前端
歡迎點贊!web
不說廢話,實現過程當中卻是遇到了一點小問題:canvas
原本嘛覺得是很簡單的:就像通常給網頁添加背景音樂,先動態建立一個audio元素,讓其隱藏起來,而後用js添加一個event事件,並觸發(事實上如今廣泛認爲的是:不能給網頁添加背景音樂。但通過猜測和實踐發現,也可經過下文第一種解決方式實現):後端
let event = new MouseEvent("click"); // 建立一個單擊事件
//給觸發元素添加屬性或者回調事件
//好比:a.download = xxx / div.onclick=function(){}
觸發元素.dispatchEvent(event); // 觸發單擊事件
可是當筆者用Google瀏覽器打卡後發現:瀏覽器禁止audio/video自動播放了:autoplay被禁用了! 除非用戶主動打開設置api
好吧聽着就有點匪夷所思,通過筆者屢次測試得出——跨域
因此咱們能夠換句話說:mp3等音頻格式的autoplay被Google禁用了!promise
沒有辦法,我只能將目光移向「元素click事件」,後來想來是我多想了——由於上面第四點的緣故,任何非用戶手動操做的「動做」都會被瀏覽器禁止。瀏覽器
Google瀏覽器爲其取了一個頗有意義的名字 —— 自動播放阻止。微信
可是我仍是發現了文檔中的一個「新」成員:web Audio API。雖然文檔中沒有描述什麼相關原理,可是經過這段描述:這讓我忽然的就想到了HTML5的另外一個「大殺器」:canvas。他也是經過一個上下文對象context凌駕於瀏覽器圖像/視頻流之上。app
★web audio api怎麼說呢,感受至少目前對大多數人用處真不大——文檔中&被廣大開發者發掘的各類騷操做canvas能作的都用canvas了,canvas不能作的對絕大多數開發者來講也不重要。
」
順着這個思路,我想到了「建立一個音軌上下文,在其中用 createBufferSource()
方法用於建立一個新的AudioBufferSourceNode接口—— 該接口能夠經過AudioBuffer對象 來播放音頻數據,以突破瀏覽器限制」,AudioBuffer對象怎麼獲取?web audio API爲了解決音頻源的問題,提出了「向音頻url發送一個請求,將數據以arraybuffer返回,再解碼獲得元數據」這樣看似複雜的方法,具體過程是這樣的:
方法使用XHR加載一個音軌,設置請求的responsetype爲ArrayBuffer使它返回一個arraybuffer數據,而後存儲在audioData變量中。而後咱們將這個arraybuffer數據置於decodeAudioData()方法中使用,當成功解碼PCM Data後經過promise回調返回, 將返回的結果經過AudioContext.createBufferSource()接口進行處理並得到一個AudioBufferSourceNode,,將源鏈接至AudioContext.destination造成一個完整的音頻流。
var context = new (window.AudioContext || window.webkitAudioContext)();
var soundBuffer = null;
function loadSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
context.decodeAudioData(request.response).then((buffer)=>{
soundBuffer = buffer;
playSound(soundBuffer);
});
};
request.send();
}
function playSound(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source[source.start?"start":"noteOn"](0);
}
//你也能夠將init放在某個按鈕觸發事件上
window.addEventListener('DOMContentLoaded', init, false);
function init() {
try {
var url = "audio/1.mp3";
loadSound(url);
} catch (e) {
alert('你的瀏覽器不支持Web Audio API');
}
}
這裏有兩個注意點:
init()
函數增長txt參數,並調用百度轉化接口,將文字先用encodeURI API轉化爲uri格式,再接入百度接口 var url = "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=" + encodeURI('這裏是字符串文本');
轉化爲url連接這段代碼很神奇:google不支持,可是控制檯裏面「萬惡的報錯」也沒有了,會給你一個提示:總之就是我不給你播放。
因此,在除了Google的其他瀏覽器中,建議將上面的API和下面這段HTML代碼一塊兒寫上:
<video controls autoplay style="display:none;"> /** 或者將controls和style都去掉 */
<source src="這裏寫要播放的音頻路徑,如:http://m10.music.126.net/20200926133756/cba79f37e90871df07cd582befe27723/ymusic/obj/w5zDlMODwrDDiGjCn8Ky/2920523350/fd2a/c111/aae2/5542b627692d3df8d63bbaeb1c73711a.mp3" type="audio/mp3"></source>
</video>
而後你應該就能夠聽到美妙動聽的背景音了!
★Firefox和Edge雖然禁掉了autoplay,可是它也是支持AudioContext API的!Google中禁止了一切不符合規範的API,並且多是由於某些不知名緣由,上面這段HTML代碼在Google中是時而能夠時而不行的,就很迷惑。。。
」
補充其實這個API最大的做用是用於音頻可視化領域——它有一個函數是這樣的:createAnalyser()
用來建立一個音域可視化對象,能夠將它鏈接到context流上:
var gainNode=context[context.createGain?"createGain":"createGainNode"]();
gainNode.connect(context.destination);
//操做完上一步後,咱們已經將音域加載到context流上,之後的操做就能夠直接鏈接這個音域對象
var analyser=context.createAnalyser();
analyser.fftSize=512;
analyser.connect(gainNode);
發現瀏覽器中有了部分實現的相關API——它曾經一直在逃避瀏覽器音頻播放政策:
function speak(sentence,pitch,volume) { //使用時調用這個函數便可
const utterance = new SpeechSynthesisUtterance(sentence);
//音調
utterance.pitch = pitch;
//音量
utterance.volume = volume;
window.speechSynthesis.speak(utterance)
}
參數 sentence 是一個字符串格式文本。
只要調用了這個函數並傳入參數,你就能在瀏覽器中聽到動聽的、求之不得的聲音了!(仍是個女聲,嘿嘿嘿) 目前, Chrome70已經廢棄這個API了。。。(由於它能夠不通過用戶主動觸發而直接播放)
固然還有穩妥一些的作法,也是個讓人比較眼前一亮的操做:是MDN文檔中提到的 Feature-Policy
頭——HTTP頭信息,可設置自動播放相關:這個屬性是給後端用的:在response中設置header!
最後
歡迎加我微信(winty230),拉你進技術羣,長期交流學習...
歡迎關注「前端Q」,認真學前端,作個專業的技術人...