您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Web Audi怎么繪制音頻圖譜”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Web Audi怎么繪制音頻圖譜”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
先介紹下小編的整體思路吧。所謂的音頻圖譜,其實只是將聲音的響度具象化為一個波形圖,響度高對應的波形高,響度低波形也就低。所以第一步,我們可以通過xhr拿到一個音頻文件的數據。那么,第二步便是如何處理這組數據,讓數據能夠比較真實的反應音頻的響度。這時候就需要前端的Web Audio Api來發揮作用了,具體如何處理,我們后面詳細說明。完成數據處理之后,最后一步就是需要根據數據繪制出波形圖,這里我們使用canvas來做波形圖的繪制。
首先,我們利用fetch,來獲取一個線上音頻。這里,我們借用一下wavesuffer官網demo中用的線上音頻來做示范。
// 音頻url let audioUrl = 'https://wavesurfer-js.org/example/media/demo.wav'; // 創建音頻上下文 let audioCtx = new (window.AudioContext || window.webkitAudioContext)(); // 創建音頻源 let source = audioCtx.createBufferSource(); /* * 通過fetch下載音頻,responseType設置為'arrayBuffer',我們以arrayBuffer格式接收返回的數據 */ fetch(audioUrl, { method: 'GET', responseType: 'arraybuffer', }).then(res => { return res.arrayBuffer(); }).then(data => { // 處理音頻數據 initAudio(data); });
拿到音頻數據之后,我們需要利用Web Audio Api,來處理音頻數據,實現音頻的播放,暫停等操作以及我們后續的波形圖繪制。這里簡單介紹下,Web Audio Api是一組非常強大的Api,它提供了在Web中控制音頻、處理音頻的一整套有效通用的系統。它能夠允許開發著,控制音頻,自選音頻源、對音頻添加特效,使音頻可視化,添加空間效果,添加混響等等。而我們今天要實現的功能,僅僅只用到了其中幾個Api,整體流程如下:
// audio 初始化 function initAudio (data) { // 音頻數據解碼 // decodeAudioData方法接收一個arrayBuffer數據作為參數,這也是為什么前面fetch音頻時設置以arrayBuffer格式接收數據 audioCtx.decodeAudioData(data).then(buffer => { // decodeAudioData解碼完成后,返回一個AudioBuffer對象 // 繪制音頻波形圖 drawWave(buffer); // 連接音頻源 source.buffer = buffer; source.connect(audioCtx.destination); // 音頻數據處理完畢 alert('音頻數據處理完畢!'); }); } // web audio 規范不允許音頻自動播放,需要用戶觸發頁面事件來觸發播放,這里我們增加一個播放按鈕,數據處理完畢后點擊播放 document.querySelector('#btn').onclick = () => { // 播放音頻 source.start(0); }
音頻數據通過AudioContext解碼后,返回一個AudioBuffer對象,這個對象,保存有音頻的采樣率、聲道、pcm數據等信息。通過getChannelData方法可以獲取到音頻某個聲道的pcm數據。返回的是一個Float32Array對象,數值范圍在-1到1之間。音頻數據比較龐大,每一秒鐘可能包含成千上萬的數據,因此我們在做圖形繪制時,需要對數據進一步采樣。比如,這里我們采用每1000條數據中,取一個最大值(正數)一個最小值(負數)來繪制圖形;
// 繪制波形圖 function drawWave (buffer) { // buffer.numberOfChannels返回音頻的通道數量,1即為單聲道,2代表雙聲道。這里我們只取一條通道的數據 let data = []; let originData = buffer.getChannelData(0); // 存儲所有的正數據 let positives = []; // 存儲所有的負數據 let negatives = []; // 先每隔100條數據取1條 for (let i = 0; i < originData.length; i += 100) { data.push(originData[i]); } // 再從data中每10條取一個最大值一個最小值 for (let j = 0, len = parseInt(data.length / 10); j < len; j++) { let temp = data.slice(j * 10, (j + 1) * 10); positives.push(Math.max.apply(null, temp)); negatives.push(Math.min.apply(null, temp)); } // 創建canvas上下文 let canvas = document.querySelector('#canvas'); if (canvas.getContext) { let ctx = canvas.getContext('2d'); canvas.width = positives.length; let x = 0; let y = 100; let offset = 0; ctx.fillStyle = '#fa541c'; ctx.beginPath(); ctx.moveTo(x, y); // canvas高度200,橫坐標在canvas中點100px的位置,橫坐標上方繪制正數據,下方繪制負數據 // 先從左往右繪制正數據 // x + 0.5是為了解決canvas 1像素線條模糊的問題 for (let k = 0; k < positives.length; k++) { ctx.lineTo(x + k + 0.5, y - (100 * positives[k])); } // 再從右往左繪制負數據 for (let l = negatives.length - 1; l >= 0; l--) { ctx.lineTo(x + l + 0.5, y + (100 * Math.abs(negatives[l]))); } // 填充圖形 ctx.fill(); } };
讀到這里,這篇“Web Audi怎么繪制音頻圖譜”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。