自從上次在趣講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
在電腦中,當咱們選中一個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。以往在處理音頻相關的需求,大可能是經過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
直接翻譯,就是"音頻上下文"。相似於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