[Voice communications] 讓音樂響起來


本系列文章主要是介紹 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。

四、參考文章

 


免責聲明!

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



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