web Audio學習與音頻播放

隨着瀏覽器的愈加強大,用瀏覽器自帶的api操做音頻已經不是難事了。咱們來使用web audio api簡單地處理下音頻資源。前端

簡介

在學習web audio api以前,先了解三個概念:git

  • 音頻源,也就是音頻輸入,能夠是直接從設備輸入的音頻,也能夠是遠程獲取的音頻文件。
  • 處理節點,分析器和處理器,好比音調節點,音量節點,聲音處理節點。
  • 輸出源,指音頻渲染設備,通常狀況下是用戶設備的揚聲器,即context.destination。

其實,音頻源和輸出源也均可以視爲節點,這三者的關係能夠用這張圖表示:github

2019-04-08_200826.png

固然,實際使用中,可能會有n個處理節點,均可以使用connect依次關聯起來。web

音頻文件播放

假如如今要用web audio api播放本地的一個音樂文件,按照前面的流程,咱們來試下。ajax

文件上傳

既然音頻文件來自本地,那麼得支持文件上傳:chrome

<input type="file" id="file" accept="audio/x-wav,audio/mpeg" />

我這兒限制了先顯示wav和mp3兩種格式。api

文件讀取

給input增長change事件,處理選中的文件:瀏覽器

var context = new (window.AudioContext || window.webkitAudioContext)();

document.getElementById('file').addEventListener('change', function(e) {
    var read = new FileReader();

    read.onload = function() {
        // 將arrayBuffer轉成audioBuffer
        context.decodeAudioData(this.result, function(buffer) {
            playSound(buffer);
        }, function() {
            console.log('error');
        });
    };
    // 利用filereader將file轉成arraybuffer格式
    read.readAsArrayBuffer(this.files[0]);
});

丟了一段代碼,咱們來看下,new AudioContext(),建立audio的上下文環境,至於webkitAudioContext是兼容較低版本的chrome的。服務器

fileReader大夥應該見到的比較多了吧,這兒用他讀取對應file對象中的文件數據,readAsArrayBuffer表示讀取結果用arrayBuffer對象顯示,因爲此方法是異步讀取的,因此只能放在onload回調中處理。微信

而咱們拿到的arrayBuffer不能直接給web audio播放,須要使用decodeAudioData()方法將arrayBuffer轉成audioBuffer,那麼此時轉化後的audioBuffer就是音頻源啦。decodeAudioData更多介紹能夠查看MDN:https://developer.mozilla.org...

注:w3c文檔上說明decodeAudioData支持audio標籤支持的全部音頻格式。

音頻播放

音頻數據到手,接下來就是播放啦。

文件上傳後,咱們拿到了音頻audioBuffer形式的數據,接下來使用createBufferSource()方法播放音頻數據,再connect到destination就能夠播放了。

// 播放音頻
function playSound(buffer) {
    var source = context.createBufferSource();

    // 設置數據
    source.buffer = buffer;
    // connect到揚聲器
    source.connect(context.destination);
    source.start();
}

一個簡單的音頻文件播放器就完成了,若是是從服務器上獲取文件也是相似的,只不過是多了個ajax處理。

代碼地址:webAudio播放本地音樂

音頻的話,能夠去一些音樂網站下載,若是懶得下的話,我這直接提供音頻下載:林俊杰_-_我還想她.mp3

小bug

當連續選擇多個文件時,你會發現,多個音頻文件一塊兒播放了,所以,多音頻輸入時,都一塊兒connect到context.destination上就能夠實現一塊兒播放了。對於此處,這應該算是個bug,查看AudioBufferSourceNode文檔,能夠利用stop()方法去處理,大夥自個想下,處理下咯。

前面的例子裏只出現了音頻源和音頻輸出,並未出現處理節點。接下來,咱們嘗試本身建立音頻,並使用音量處理節點。

自制音頻並播放

建立音頻源

此處咱們不使用外部的音頻文件,而是使用createOscillator()方法建立音頻源。

該方法返回OscillatorNode,能夠經過frequency屬性設置他的振盪頻率,type屬性則能夠用來指定要播放的波形。更多屬性和方法參考OscillatorNode文檔

var context = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = context.createOscillator();
// oscillator.type = 'sine';
// oscillator.frequency.value = 800;  // 頻率800Hz,默認440

建立音量處理節點

使用createGain()方法,修改返回值中的value,既能夠改變音量大小。

var gainNode = context.createGain();
gainNode.gain.value = 0.8; // 音量 0 ~ 1

節點關聯與播放

將這些」節點」connect起來就能夠播放了。

oscillator.connect(gainNode); // 音頻源關聯到音量
gainNode.connect(context.destination); // 音量關聯到揚聲器

// chrome 73 須要用戶點擊纔可播放
document.getElementById('start').addEventListener('click', function() {
    oscillator.start();
});

雖然播放後是一片噪音,不過簡單的web audio api咱們已經會使用啦。

代碼地址:webAudio製造噪音並播放

其餘

本身嘗試過程當中,在控制檯下遇到這個警告:

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

2019-04-09_191004.png

大概意思就說AudioContext須要用戶手動觸發,因此只須要將new AudioContext()移動到事件內部就好了。

總結

咱們已經可以使用web audio播放本地音樂和製造噪音了,接下來,能夠嘗試下其餘的api了。

閱讀原文

歡迎關注微信公衆號[ 我不會前端 ]或掃描下方二維碼!

weixin8cm.jpg

相關文章
相關標籤/搜索