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