摘要:其實這個能做的事不光是音頻可視化。其實這次寫博客之前還完善了一下,給加上了通過設備的麥克風獲取音頻并可視化的方法。世界晚安參考基于實現音頻可視化效果本文作者本文鏈接利用實現音頻可視化
音頻可視化實現之后真的很酷,雖然這次只是跟著MDN上的教程學習了一下,照著Demo敲了一遍而已。但收獲頗多,記錄于此。
web audio api先來感受一下 web audio api 的基礎概念,下面截取一段MDN上的介紹。具體的請移步文檔
Web audio 概念與使用Web Audio API使用戶可以在音頻上下文(AudioContext)中進行音頻操作,具有模塊化路由的特點。在音頻節點上操作進行基礎的音頻, 它們連接在一起構成音頻路由圖。即使在單個上下文中也支持多源,盡管這些音頻源具有多種不同類型通道布局。這種模塊化設計提供了靈活創建動態效果的復合音頻的方法。
在跟著文檔和Demo走了一遍之后,我自己的理解就是,我們可以通過const audioCtx = new (window.AudioContext || window.webkitAudioContext)()這樣的形式來獲取/創建一個音頻上下文,這個audioCtx中有許多可供使用的屬性方法。這里只會稍微描述一下實現音頻可視化要用的屬性。具體的可以參考文檔。
其實這個AudioContext能做的事不光是音頻可視化。首先它支持獲取音頻的輸入,也就是接下來會提到的定義音頻源。然后它能夠定義音效,或許你要是知道怎么把一段聲音做成電音的算法,那你可以試試,然后教教我。哈哈哈,當然一些基礎的控制音頻源的輸出音量這些都是有的。
接下來就繼續談音頻可是化啦
音頻可視化首頁我們需要選擇一個用來展示音頻的工具,這里其實用的就是Canvas,當然如果你會用Svg也可以嘗試著做一下。這里我不會svg,嗯。打算學(but, who knows when)。
那么這里就只剩下用來顯示的數據了。
前面提到過,AudioContext中有許多屬性和方法,其中就有createAnalyser()方法,可以供我們獲取AnalyserNode這個對象。這個對象會提供給我們用來顯示(可以被我們處理成用來顯示的)的所需要的數據。
AnalyserNode這里還是得簡單提一下AnalyserNode,我們接下來需要用到它的幾個屬性和方法
AnalyserNode.fftSize
一個無符號長整形(unsigned long)的值, 用于確定頻域的?FFT (快速傅里葉變換) 的大小。
AnalyserNode.getByteFrequencyData()
將當前頻域數據拷貝進Uint8Array數組(無符號字節數組)。
AnalyserNode.getByteTimeDomainData()
將當前波形,或者時域數據拷貝進?Uint8Array數組(無符號字節數組)。
這里直接copy了MDN的內容。然后我再根據自己的理解來描述一下。
AnalyserNode.fftSize
首先我們可以通過設置AnalyserNode.fftSize來控制將要用來顯示的數據(數組,這里后面會處理成數組)的個數(長度),簡單點說就是,如果我們想用柱狀圖來顯示數據,fftSize設置的越大,那我們顯示的柱子的數量就會越多。反之同理。不過這個值是有范圍的,并且必須是2的n次冪。范圍:[32, 32768],超出或小于會報錯。
AnalyserNode.getByteFrequencyData()
這個在文檔中描述是獲取當前頻域的數據,我理解成就是如果要顯示成柱狀圖的形式,那么就用這個。因為我試過了用getByteTimeDomainData結果并不是很好。因為getByteTimeDomainData是用用來展示波形的,這里我理解的就是文檔的字面意思。不展開描述
好的,這里要用到的關鍵的基礎知識介紹完畢。接下來就是要做事了,直接上代碼了。
實現一下接下來是一些供描述的代碼,具體的代碼在我的Github上,其實直接看MDN提供的Demo的源代碼也行。
// 獲取頁面中的audio對象 const myAudio = document.querySelector("audio") // 獲取web audio 上下文對象 const audioCtx = new (window.AudioContext || window.webkitAudioContext)() // 獲取聲音源 const source = audioCtx.createMediaElementSource(myAudio) // 獲取分析對象 const analyser = audioCtx.createAnalyser() // 設置fftSize analyser.fftSize = 1024 const bufferLength = analyser.fftSize // 因為這里analyser返回的數據js不能直接使用,所以要通過Uint8Array來轉換一下,讓js認識一下 const dataArray = new Uint8Array(bufferLength) // 連接解析器 source.connect(analyser) // 輸出音頻 source.connect(audioCtx.destination)
以上就已經可以獲取當前audio對象所播放音頻的可供我們js使用的數據了,話有點繞,其實這里要用到的就是這個daraArray,我們需要在接下來編寫canvas的代碼中用到這個數組中的數據。
畫重點這里我踩了個坑,我一開始沒寫source.connect(audioCtx.destination)便運行了上面剩余的代碼,發現頁面沒有聲音,但是我如果不寫這些代碼。直接用audio標簽autoplay,聲音是很洪亮的。但是用了上面的代碼就是沒聲音。
然后我注意到Demo中還有一句source.connect(audioCtx.destination)我沒寫。加上之后,確實出了聲音。于是我看了一下文檔得知,這個是用來定義音頻目的地的。也就是說,在我們把音頻源傳入AudioContext之后,這個音頻源就被AudioContext托管了。然后AudioContext并不會自動播放聲音,這里需要手動設置一下音頻的歸屬地(通常是輸出到你的揚聲器)
那么接下來就是把數據顯示出來了,這里我直接粘貼處理canvas的代碼了(困了,現在半夜12:13)
const draw = () => { // 獲取當前聲音的波形;將當前波形,或者時域數據拷貝進 Uint8Array數組(無符號字節數組) analyser.getByteTimeDomainData(dataArray) ctx.clearRect(0, 0, W, H) ctx.fillStyle = "rgb(200,200,200)" ctx.fillRect(0, 0, W, H) ctx.strokeStyle = "rgb(0,0,0)" ctx.beginPath() const sliceWidth = W * 1.0 / bufferLength let x = 0 for (let i = 0; i < bufferLength; i++) { let v = dataArray[i] / 128.0 let y = v * H / 2 if (i === 0) { ctx.moveTo(x, y) } else { ctx.lineTo(x, y) } x += sliceWidth } ctx.lineTo(W, H / 2) ctx.stroke() requestAnimationFrame(draw) } const draw2 = () => { // 獲取當前頻域數據;將當前頻域數據拷貝進Uint8Array數組(無符號字節數組) analyser.getByteTimeDomainData(dataArray) ctx.clearRect(0, 0, W, H) ctx.fillStyle = "rgb(0,0,0)" ctx.fillRect(0, 0, W, H) const barWidth = (W / bufferLength) * 2.5 let barHeight let x = 0 for (let i = 0; i < bufferLength; i++) { barHeight = dataArray[i] / 2 ctx.fillStyle = `rgb(${barHeight + 100},50,50)` ctx.fillRect(x, H - barHeight, barWidth, barHeight) x += barWidth + 1 } requestAnimationFrame(draw2) }
這里有兩個方法,分別:draw是用來顯示波形的,draw2是可以顯示成柱狀圖的樣子,我個人更喜歡draw2畫出來的樣子。
因為這次是分享web audio api,而且上面canvas的代碼比較簡單,看看就好了。就不展開講了。
最后BB了好久,就總結一下了,希望有人能看到這里。
這次知道寫web audio api 也其實就是簡單的介紹了一下這個強大的api能支持網頁對音頻作出來的各種騷操作。不光光是可視化,變聲,換成立體環繞啥的都是不在話下的。有興趣的同學可以了解一下。嗯,了解一下,然后教教我。
其實這次寫博客之前還完善了一下,給加上了通過設備的麥克風獲取音頻并可視化的方法。挺簡單的,看看源碼就知道了。
或許過兩天會給這篇加上點圖片,放個demo的地址吧。
不早了 睡了。世界晚安
參考- 基于Web Audio API實現音頻可視化效果
- HTML5 Audio: createMediaElementSource breaks audio output
- AnalyserNode
- web audio api
本文作者: Roy Luo本文鏈接: 利用 web audio api 實現音頻可視化
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97044.html
摘要:前言本文翻譯自上的利用,這是中的的一個入門教程。原文是英文,但有日本同志翻譯的日文版。這是為了提供一個基本的低音増幅效果在這個例子中可以設定過濾器的種類,周波數,甚至的值。如果是過濾器的話,可以提供一個比指定周波數低的低音増幅。 前言 本文翻譯自MDN上的《Web Audio APIの利用》,這是HTML5中的Web Audio API的一個入門教程。原文是英文,但有日本同志翻譯的日文...
摘要:高動態范圍,采用進行內部處理。這最大限度地減少體積驟降音頻區域之間,從而導致更均勻的交叉衰減,可能是在電平略有不同區域之間。低通濾波器保持較低的頻率范圍,但丟棄高頻。 引用 Getting Started with Web Audio APIhttp://www.html5rocks.com/en/tutorials/webaudio/intro/ Introduction Audio...
摘要:一直覺得網易云音樂的用戶體驗是很不錯的,很早就注意到了里面的鯨魚音效,如下圖,就是一個環形的跟著音樂節拍跳動的特效。 一直覺得網易云音樂的用戶體驗是很不錯的,很早就注意到了里面的鯨魚音效,如下圖,就是一個環形的跟著音樂節拍跳動的特效。 showImg(https://segmentfault.com/img/remote/1460000017090441); gif動圖可能效果不太理想...
閱讀 3878·2021-09-27 13:36
閱讀 4554·2021-09-22 15:12
閱讀 3063·2021-09-13 10:29
閱讀 1826·2021-09-10 10:50
閱讀 2360·2021-09-03 10:43
閱讀 518·2019-08-29 17:10
閱讀 442·2019-08-26 13:52
閱讀 3249·2019-08-23 14:37