Web Audio介紹


Web Audio還是一個比較新的JavaScript API,它和HTML5中的<audio>是不同的,簡單來說,<audio>標簽是為了能在網頁中嵌入音頻文件,和播放器一樣,具有操作界面,而Web Audio則是給了開發者對音頻數據進行處理、分析的能力,例如混音、過濾等,類似於對音頻數據進行PS。

一般的網站應用應該是用不倒這些API中的,但是一些游戲引擎或者在線音樂編輯等類型的網站應該用得到。

Web Audio API緊緊圍繞着一個概念設計:audio context,它就像是一個有向圖,途中的每個節點都是一個audio node,音頻數據從源節點按照程序中指定的邊一步一步的走的目的節點。
如果你接觸過directshow開發,audio context就像filter manager,而audio node則是各種filter,當然,如果你是個linux開發者,這有看起來像是pipe。一個audio context中的audio node可以有很多,上面的是最簡單的形式了。而audio node又包括四種,
1. 源節點(source node)
2. 處理節點(gain node、panner node、wave shaper node、oscillator node、delay node、convolver node等)
4. 目的節點(destination node)

# Development #

#### 初始化audio context ####

現在只有firefox和webkit系的瀏覽器(chrome、safari、opera)都支持web audio api,不過和其他新標准一樣,每家瀏覽器還是使用了特定的前綴,所以在調用API時,要考慮一下這個問題。

window.AudioContext = (window.AudioContext || window.webkitAudioContext);
if(window.AudioContext) {
    var context = new window.AudioContext();
} else {
    console.log('not support web audio api');
}

一個audio context對象可以支持多個節點,包括source和destination節點,每個新創建的audio context都有一個默認的目的節點,通常代表當前機器上的默認音頻輸出設備,可以通過context.destination來獲取。

#### 創建audio node ####

// create source node
var source = context.createBufferSource();
// create gain node
var gain = context.createGain();
#### audio node之間的鏈接、斷開操作 ####

// connect source to gain
source.connect(gain);
// connect gain to node
gain.connect(context.destination);

// disconnect source from gain
source.disconect(0);
// disconnect gain from destination
gain.disconnect(0);

  

#### 播放聲音 ####

所謂巧婦難為無米之炊,沒有聲音再好的API也出不來。那么如何得到音頻數據呢?既然成為Web Audio,數據肯定是從web上來。下面就是從服務器端下載音頻文件,然后解碼播放的代碼片段。

var context = createAudioContext();

var audioURl = 'http://...'; // 這里替換為音頻文件URL
var xhr = new XMLHttpRequest();
xhr.open('GET', audioURL, true);
xhr.responseType = 'arraybuffer'; // XMLHttpRequest 2的新東西
xhr.onload = function() {
    // 音頻數據在request.response中,而不是request.requestText
    context.decodeAudioData(request.response, function (buffer) {
        source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.start(0); // 0是當前audio context中的同步時間
    }
}
xhr.send();

#### 時間控制 ####

web audio提供了非常精准的時間控制,所有的時間都是以秒來計數的。是的,你沒看錯,是秒,不過這里的秒在底層都是使用高精度的浮點數存儲的,其實際精確度是很高的。在創建的audio context中都有一個同步系統,用來對外提供絕對時間,這個時間可以通過context.currentTime獲取。這個絕對時間從0開始,而且一旦新建context,就開始走了。

使用代碼source.start(time)中,則要求在絕對時間為time時開始播放,當然,如果這個時間time小於context.currentTime則會立即播放,所以上面代碼片段中的source.start(0),其實就是立即播放的意思,如果要指定在N秒后播放,則要使用source.start(context.currentTime + N)。

source.start還可以指定另外兩個參數,一個是音頻的開始時間,一個音頻的持續時間,例如一個一分鍾的視頻,你可以使用source.start(10, 20, 30)來指定10秒后播放音頻文件20秒到20 + 30秒之間的內容。至於暫停、繼續功能,則需要自己手工的記錄時間點,web audio自身是不提供這些功能的,另外一點就是,web audio的定時功能是不可取消的,嫁出去的姑娘,潑出去的水啊。

var startOffset = 0; // audio file offset
var startTime = 0; // web audio absolute time

function start() {
    startTime = context.currentTime;
    var source = context.createBufferSource();
    source.buffer = buffer;
    source.loop = true;
    source.connect(context.destination);
    source.start(0, startOffset % buffer.duration);
}

function pause() {
    source.stop();
    // 已經播放了多長時間
    startOffset += context.currentTime - startTime;
}

function resume() {
    // 和<audio>標簽嵌入的音頻文件不同,source node是不能重復播放的,所以繼續功能其實就是play
    play();
}

到此為止,就是web audio最基本的應用。當然,web audio不止這么簡單,使用其他類型的audio node,基本可以完成一個小型的混音室。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM