本系列文章主要是介紹 Web Audio API 的相關知識,由於該技術還處在 web 草案階段(很多標准被提出來,至於取舍需要等待穩定版文檔來確定,草案階段的文檔很多都會被再次編輯甚至重寫、全部刪除等,不適合作為正式參考),很多 API 都是未確定的,目前支持 Web Audio API 的瀏覽器是較新版的 Google Chrome 和 FireFox,其他瀏覽器暫時還沒有兼容。
現在的網絡硬件環境還沒有達到普遍語音通信的條件,但是 web語音通信 一定會成為后期 web 研究的一個重要話題,憑着一點個人興趣,拿出來研究研究~
本文主要介紹 Web Audio API 的相關特性,以及音頻源的獲取方式。
本文地址:http://www.cnblogs.com/hustskyking/p/webAudio-listen.html,轉載請注明源地址。
一、Web Audio
在 <audio>
標簽的到來之前,Flash 以及其他的插件相繼打破 web 的寧靜,而如今 audio 被送到了 web 開發之中,我們再也不需要引用各種插件來播放聲音了。
1. Web Audio API 的特性
Web Audio API 是 JavaScript 中主要用於在網頁應用中處理音頻請求的一個高級應用接口,這個 API 目的是用於讓最新技術與傳統的游戲音頻引擎的綜合處理相兼容,也即盡力提供一些桌面音頻處理程序的要求。
- 查看音頻播放期間調度事件發生的確切時間;
- 支持各種類型的音頻過濾波器以實現各種效果,包括回聲、消除噪音等;
- 支持利用合成聲音(Sound synthesis)創建電子音樂;
- 支持3D位置音頻模擬效果,比如某種聲音隨着游戲場景而移動;
- 支持外部輸入的聲音與 WebRTC 進行集成(調用 WebRTC ,在你的設備中增添吉他聲),或者在 WebRTC 中調用其他地方傳輸過來的聲音;
- 利用音頻數據分析創造良好的可視化聲音等。
2. AudioContent 簡介
Web Audio API 可以用來操作或者播放網頁以及應用中的 audio 資源,在一個 Audio上下文環境(AudioContext)中,有各種 Audio節點(AudioNode),如:
Interface | description |
---|---|
AudioContext | 包含表示連接中間件 AudioNodes 的音頻信號曲線圖 |
AudioNode | 表示 audio源,audio輸出以及 中間處理模塊,他處在 AudioContext 的上下文中 |
AudioDestinationNode | 他是 AudioNode 的一個子類,表示所有被渲染音頻流到達的最終地點 |
AudioBuffer | 表示 audio資源 的一個臨時緩存,可表示一個音頻剪輯 |
AudioBufferSourceNode | 從 AudioBuffer 中生成 audio 的 AudioNode 節點 |
ScriptProcessorNode | 一個可以直接被 JS 操作的 AudioNode 節點 |
GainNode | 音頻增益節點 |
OscillatorNode | 一個可產生固定頻率的 audio 源 |
還有其他的 API 可以查看http://www.w3.org/TR/webaudio/#APIOverview.
使用 AudioContext 實例,我們可以將生成的一個或者多個音頻流連接到聲音的輸出位置,這個連接並不一定是直接送到輸出端,期間可以使用 AudioNodes 作為中繼器和處理器,讓這些聲音信號有一個更好的效果。
單個 AudioContext 實例可以支持多音頻的輸入,所以對於一個 audio 應用我們只需要創建一個實例就行了。很多諸如創建一個 AudioNode 節點、解碼音頻文件等方法都是 AudioContext 的內置方法。創建一個 AudioContext 上下文也十分簡單:
var context; try{ window.AudioContext = window.AudioContext || window.webkitAudioContext; context = new AudioContext(); } catch(e) { alert('請更新至最新版的 Chrome 或者 Firefox'); }
二、音頻流的獲取
1. 標簽引入
標簽引入是最直接的方式,
<audio autoplay src="http://qianduannotes.duapp.com/file/tankWar.mp3"> 瀏覽器不支持 audio 標簽。 </audio>
如果瀏覽器不支持 audio 標簽,便會將其當做一個普通元素來解析,中間一行字也就會被顯示出來。而支持 audio 標簽的瀏覽器會忽略標簽內任何文本。我們還可以為他加上 autoplay 、loop 等屬性,使音頻在進入頁面之后立即循環播放。
<audio autoplay="autoplay" controls="controls" src="http://qianduannotes.duapp.com/file/tankWar.mp3"> 瀏覽器不支持 audio 標簽。 </audio>
controls 屬性是用來控制顯示音頻文件的控制部分的。默認未設置 controls 屬性。
2. webRTC mediaStream Media Capture (多謝@Hehe123提醒,RTC屬於通信了,此處只是獲取 media 流)
利用 getUserMedia 拿到本地的音頻流。
// 前綴處理 window.AudioContext = window.AudioContext || window.webkitAudioContext; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; var context = new AudioContext(); navigator.getUserMedia({audio: true}, function(stream) { // 獲取本地流送入 AudioContext var microphone = context.createMediaStreamSource(stream); // filter為一個中間處理器,用來過濾音頻 var filter = context.createBiquadFilter(); // microphone -> filter -> destination. microphone.connect(filter); filter.connect(context.destination); }, function(){ console.log("出了點問題~ 是否在服務器環境下運行?"); });
這里需要注意的是,使用 webRTC 需要在服務器環境下,你可以搭建一個本地服務器,也可以把代碼上傳到遠程服務器上測試。
3. FileSystem
選擇本地文件,讀取音頻流,拿到 Blob 流地址,送入 audio 中
<input type="file" onchange="return run(this.files);" /><br /><br /> <audio controls id="audio"></audio> <script type="text/javascript"> function run(files){ var blob = window.webkitURL.createObjectURL(files[0]); audio.src = blob; audio.autoplay = "autoplay"; } </script>
4. 移動設備,還可以使用如下方式
1)HTML Media Capture
<input type="file" accept="audio/*;capture=microphone">
2)device 元素
<device type="media" onchange="update(this.data)"></device> <audio autoplay></video> <script> function update(stream) { document.querySelector('audio').src = stream.url; } </script>
5. 從鍵盤獲取
本質並不是從鍵盤獲取,而是通過鍵盤獲取到我們設定的頻率值,然后通過程序創建一段音頻。如下面的程序:
下面例子中可以按鍵盤上中間的一排按鍵(A到K)來發出不同的聲音。
var AudioContext=AudioContext||webkitAudioContext; var context=new AudioContext; //為每個鍵盤位對應一個頻率 var s={65:256,83:288,68:320,70:341,71:384,72:426,74:480,75:512}; //為每個頻率創建一個Oscillator for(var i in s) value=s[i], s[i]=context.createOscillator(), s[i].frequency.value=value, s[i].start(); //鍵盤按下時將相應頻率的Oscillator連接到輸出源上 addEventListener("keydown",function(e){ if(e=s[e.keyCode])e.connect(context.destination); }); //鍵盤松開時將相應頻率的Oscillator的連接取消 addEventListener("keyup",function(e){ if(e=s[e.keyCode])e.disconnect(); });
這段代碼引自次碳酸鈷的博客.
三、小結
本文是個介紹性的文章,提到了 Web Audio API 的相關知識,以及如何在你的 web 程序中引入 音頻流。沒有寫相關 demo,感興趣的童鞋可以復制代碼自己去測試,在后續文章中會給出測試 DEMO。
四、參考文章
- http://www.csdn.net/article/2013-07-10/2816178-Web-Audio-API-Firefox CSND
- https://hacks.mozilla.org/2013/07/web-audio-api-comes-to-firefox/ Mozilla
- http://www.html5rocks.com/en/tutorials/webaudio/intro/#toc-context html5rocks
- http://www.w3.org/TR/webaudio/ W3 Group
- http://www.web-tinker.com/article/20497.html 次碳酸鈷