初識HTML5 Web Audio API

前言

自從上次在趣講CDN一文中講了一個"傳東奶"的故事以後,就再也沒有發過博客。或許有些朋友還覺得咱們被抓了呢,哈哈哈~javascript

好久之前,趙忠祥老師就告訴咱們,雨季,是個好時節。雨季來了,春暖花開,萬物復甦,又到了大草原上程序猿們XX的季節。好吧,扯遠了。說到底,就是團隊中的小哥哥小姐姐都忙着談戀愛,都沒時間寫博客了。html

獲取音頻的時長

有這樣的一個需求,上傳一個音頻文件,同時獲取其大小及時長。html5

常規方法

這很簡單,使用記憶中的那些方法,寫出下面的代碼:java

function getAudioDuration(url) {
  const audio = document.createElement('audio');
  audio.src = url;
  audio.addEventListener("canplay", function () {
		console.log(audio.duration);
  });
}

const file = document.getElementById('file');
file.addEventListener('change', (e) => {
  const file = e.target.files[0];
  console.log(file.size);
  getAudioDuration(URL.createObjectURL(file));
})
複製代碼

當我擼完上面這段代碼的時候,回想起總工的批判:這方案太簡單了。菊花一緊,嚇得我趕忙找找其餘的方案。git

ArrayBuffer

在電腦中,當咱們選中一個MP3文件的時候,一般能夠看到一些元信息,好比播放時長、採樣速率等。既然如此,咱們是否能夠經過讀取二進制數據來獲取對應的信息呢?github

在查詢相關資料以後,發現了decodeAudioData這個API能夠知足咱們的需求,因而有了下面的方案。web

function getAudioDurationByAudioApi(file) {
    const fileReader = new FileReader();
    const audioContext = new AudioContext();
    fileReader.readAsArrayBuffer(file);
    fileReader.onload = () => {
        audioContext.decodeAudioData(fileReader.result, (result) => {
            console.log(result);
        });
    }
}

const file = document.getElementById('file');
file.addEventListener('change', (e) => {
    const file = e.target.files[0];
    console.log(file.size);
    getAudioDurationByAudioApi(file);
})
複製代碼

被忽略的Web Audio API

經過以上的探索,發現了一直被我忽略的Web Audio API。以往在處理音頻相關的需求,大可能是經過audio標籤,播放一段音頻,很簡單。因此也就沒有關注到早已存在的Audio API。canvas

舉個栗子

實際應用一下,舉個簡單的播放音頻栗子:api

function playAudio(file) {
    const fileReader = new FileReader();
    const audioContext = new AudioContext();
    fileReader.readAsArrayBuffer(file);
    fileReader.onload = () => {
        audioContext.decodeAudioData(fileReader.result, (result) => {
          //建立播放源
          const source = audioContext.createBufferSource();
          source.buffer = result;
          //鏈接輸出終端
          source.connect(audioContext.destination);
          //開始播放
          source.start();
        });
    }
};

const file = document.getElementById('file');
file.addEventListener('change', (e) => {
    playAudio(e.target.files[0]);
});
複製代碼

以上例子簡單使用相關的API進行了音頻的播放,分析一下關鍵的代碼。wordpress

AudioContext

直接翻譯,就是"音頻上下文"。相似於canvas中的context。其中包含了一系列用來操做音頻的API。

上面的代碼中,經過const audioContext = new AudioContext();建立了一個AudioContext對象,因而咱們就能夠進行各類各樣的操做。

建立播放源

上面的例子中,咱們經過AudioContext.createBufferSource()建立了播放源。除此以外,咱們還可使用其餘的數據做爲播放源:

具體介紹可點擊連接查看。

鏈接輸入輸出

咱們能夠看到,在設置好播放源以後,進行了一個connect操做。這個操做就是將播放源連接到播放終端。

AudioContext的destination屬性返回一個AudioDestinationNode表示context中全部音頻(節點)的最終目標節點,通常是音頻渲染設備,好比揚聲器。

有趣的玩法

在學習AudioContext相關API的過程當中,發現了createAnalyser這個方法。

createAnalyser方法能建立一個AnalyserNode,能夠用來獲取音頻時間和頻率數據,以及實現數據可視化。

要看看效果吧,demo

之前,須要標識一個音頻正在播放,咱們常常會放一個跳動的gif。好比:

是的,這一點都不酷。不由又回想起總工的那句話:這方案太簡單了。

之後,咱們再作這樣的需求的時候,就能夠作成跟隨音樂頻率跳動的動畫效果了。

總結

魯迅先生說:"歷來如此,便對嗎?"

是啊,咱們應該對現有方案多點思考。

以上所述,僅僅只是Web Audio API的冰山一角,還有更多高級的玩法,有興趣的能夠查看相關的文檔。

相關文章

@Author:TDGarden

相關文章
相關標籤/搜索