成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

利用 web audio api 實(shí)現(xiàn)音頻可視化

PingCAP / 2477人閱讀

摘要:其實(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

相關(guān)文章

  • 努力翻譯一篇中文最友好的,Web Audio API的使用相關(guān)的文章

    摘要:前言本文翻譯自上的利用,這是中的的一個(gè)入門(mén)教程。原文是英文,但有日本同志翻譯的日文版。這是為了提供一個(gè)基本的低音増幅效果在這個(gè)例子中可以設(shè)定過(guò)濾器的種類,周波數(shù),甚至的值。如果是過(guò)濾器的話,可以提供一個(gè)比指定周波數(shù)低的低音増幅。 前言 本文翻譯自MDN上的《Web Audio APIの利用》,這是HTML5中的Web Audio API的一個(gè)入門(mén)教程。原文是英文,但有日本同志翻譯的日文...

    caikeal 評(píng)論0 收藏0
  • 那些 audio api的事 (一) AudioContext

    摘要:高動(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...

    沈儉 評(píng)論0 收藏0
  • 利用AudioContext來(lái)實(shí)現(xiàn)網(wǎng)易云音樂(lè)的鯨魚(yú)音效

    摘要:一直覺(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)圖可能效果不太理想...

    cod7ce 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<