網頁播放音樂這個常識應該都知道,畢竟百度 MP3 搜索可是風靡一時!
但使用瀏覽器無中生有的創建音頻,在 HTML5 規範落地之前可是一片空白。
AudioContext 的體量與 Canvas 差不了多少,一個針對圖形圖像,一個用於音頻,兩者結合起來就把 flash 給拉下了神壇~~
本文源之於一次技術研究,曾經有一個需求要用 H5 搞一個網頁 K 歌,技術難點在於要將原唱、伴唱、錄音的音頻數據進行合併,後來尋尋覓覓的找到了 AudioContext 這個 API,雖然最終沒用 H5 去實現,不過還是漲了見識!!
不廢話,直接看代碼:
<button id="button">經過我</button>
<script>
window.AudioContext = window.AudioContext || window.webkitAudioContext;
(function () {
if (!window.AudioContext) {
alert('當前瀏覽器不支持Web Audio API');
return;
}
// 按鈕元素
var eleButton = document.getElementById('button');
// 創建新的音頻上下文接口
var audioCtx = new AudioContext();
// 發出的聲音頻率數據,表現為音調的高低
var arrFrequency = [196.00, 220.00, 246.94, 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25, 587.33, 659.25, 698.46, 783.99, 880.00, 987.77, 1046.50];
// 音調依次遞增或者遞減處理需要的參數
var start = 0, direction = 1;
// 鼠標hover我們的按鈕的時候
eleButton.addEventListener('mouseenter', function () {
// 當前頻率
var frequency = arrFrequency[start];
// 如果到頭,改變音調的變化規則(增減切換)
if (!frequency) {
direction = -1 * direction;
start = start + 2 * direction;
frequency = arrFrequency[start];
}
// 改變索引,下一次hover時候使用
start = start + direction;
// 創建一個OscillatorNode, 它表示一個週期性波形(振盪),基本上來説創造了一個音調
var oscillator = audioCtx.createOscillator();
// 創建一個GainNode,它可以控制音頻的總音量
var gainNode = audioCtx.createGain();
// 把音量,音調和終節點進行關聯
oscillator.connect(gainNode);
// audioCtx.destination返回AudioDestinationNode對象,表示當前audio context中所有節點的最終節點,一般表示音頻渲染設備
gainNode.connect(audioCtx.destination);
// 指定音調的類型,其他還有square|triangle|sawtooth
oscillator.type = 'sine';
// 設置當前播放聲音的頻率,也就是最終播放聲音的調調
oscillator.frequency.value = frequency;
// 當前時間設置音量為0
gainNode.gain.setValueAtTime(0, audioCtx.currentTime);
// 0.01秒後音量為1
gainNode.gain.linearRampToValueAtTime(1, audioCtx.currentTime + 0.01);
// 音調從當前時間開始播放
oscillator.start(audioCtx.currentTime);
// 1秒內聲音慢慢降低,是個不錯的停止聲音的方法
gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1);
// 1秒後完全停止聲音
oscillator.stop(audioCtx.currentTime + 1);
});
})();
</script>
以上代碼內容來源於大佬張鑫旭的博客:https://www.zhangxinxu.com/wordpress/2017/06/html5-web-audio-api-js-ux-voice/
注意:AudioContext 必須要在在用户有交互之後才能創建!!意思就是用户在網頁上有點擊操作之後才能開始播放音頻。
否則報錯警告:
The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.
效果預覽
可長按以下二維碼跳轉到大佬的體驗地址:
{% asset_img qrcode.jpg %}
二維碼鏈接:https://www.zhangxinxu.com/study/201706/button-hover-web-audio.html
其他示例
1、 oscillator.type 不同波形帶來的聲音效果:
https://codepen.io/gregh/pen/LxJEaj
2、又有大佬使用 AudioContext 搞出了小時候玩的遊戲音樂:
https://codepen.io/gregh/pen/xqWwqz
寫在最後
AudioContext 的 API 絕不止用來創建音頻這麼簡單,往大了想一下,Canvas 可以把 PS 搬到瀏覽器,那些專業的音頻處理軟件是不是也可以搬到線上?
看看大佬對 AudioContext 的看法:

參考資料
https://www.zhangxinxu.com/wordpress/2017/06/html5-web-audio-api-js-ux-voice/
https://developer.mozilla.org/zh-CN/docs/Web/API/AudioContext