JavaScript+Canvas實(shí)現(xiàn)繪制音頻可視化波形圖
1. 效果演示

上圖演示了音頻的波形隨著音樂的節(jié)奏而跌宕起伏
2. 基本概念說明
2.1 音頻源節(jié)點(diǎn)
音頻數(shù)據(jù)的來源,是音頻處理的其中一個(gè)環(huán)節(jié)
2.2 時(shí)域圖

聲音信號(hào)是一維的時(shí)域信號(hào),無法觀察出頻率隨時(shí)間的變化規(guī)律
橫軸代表時(shí)間, 縱軸是信號(hào)的變化(振幅)
2.3 頻譜圖

任何信號(hào)(當(dāng)然要滿足一定的數(shù)學(xué)條件),都可以通過傅立葉變換而分解成一個(gè)直流分量(也就是一個(gè)常數(shù))和若干個(gè)(一般是無窮多個(gè))正弦信號(hào)的和
每個(gè)正弦分量都有自己的頻率和幅值,頻率值作橫軸,幅值作縱軸
3. 案例代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas在音頻可視化的應(yīng)用</title>
</head>
<body>
<canvas></canvas>
<audio src="./1.mp3" controls></audio>
<script>
const audio = document.querySelector('audio')
const canvas = document.querySelector('canvas')
const con = canvas.getContext('2d')
// 初始化canvas的尺寸
canvas.width = window.innerWidth // 窗口的內(nèi)部寬度
canvas.height = window.innerHeight / 2 //窗口的內(nèi)部高度
document.body.style.backgroundColor = '#000000' // 背景顏色設(shè)置為黑色
// 定義數(shù)組和音頻分析器
let dataArray, analyser
audio.onplay = () => {
// 初始化
const audCon = new AudioContext() // 創(chuàng)建音頻上下文
const source = audCon.createMediaElementSource(audio) // 創(chuàng)建音頻源節(jié)點(diǎn)
// 創(chuàng)建音頻分析器
analyser = audCon.createAnalyser()
// 快速傅里葉變換的長(zhǎng)度必須為2的整數(shù)冪
analyser.fftSize = 512 // 這里把快速傅里葉變換的長(zhǎng)度設(shè)置為512
// 連接音頻源節(jié)點(diǎn)到音頻分析器上
source.connect(analyser)
// 連接音頻分析器到音頻終端上
analyser.connect(audCon.destination)
// 創(chuàng)建數(shù)組,用于接收分析器節(jié)點(diǎn)的分析數(shù)據(jù)
// Uint8Array 數(shù)組類型表示一個(gè) 8 位無符號(hào)整型數(shù)組
// frequencyBinCount是fftSize值的一半作為可視化音頻的數(shù)組長(zhǎng)度
dataArray = new Uint8Array(analyser.frequencyBinCount)
}
// 把分析出的波形繪制到canvas上
(function draw() {
// 動(dòng)畫幀,按幀繪制canvas
requestAnimationFrame(draw)
// 清空畫布
const { width, height } = canvas
con.clearRect(0, 0, width, height)
// 讓分析器節(jié)點(diǎn)分析出數(shù)據(jù)到數(shù)組中
analyser.getByteFrequencyData(dataArray)
// 設(shè)置canvas上下文繪制的顏色
con.fillStyle = 'skyblue'
// len表示獲取分析到的音頻數(shù)據(jù)數(shù)組長(zhǎng)度的
// 這里除以2.5是剔除不經(jīng)常出現(xiàn)的高頻的部分
const len = dataArray.length / 2.5
// barWidth表示每個(gè)波形矩形的寬度
// 這里除以2是為了繪制對(duì)稱的波形圖
const barWidth = width / len / 2
for (let i = 0; i < len; i++) {
// data是8位數(shù)組的每個(gè)數(shù)據(jù),因?yàn)槭且粋€(gè)字節(jié),即data的值都是 <= 255
const data = dataArray[i]
// barHeight表示每個(gè)波形矩形的高度,值為單位長(zhǎng)度乘canvas容器的高
const barHeight = (data / 255) * height
// 繪制點(diǎn)y
const y = height - barHeight
// 繪制點(diǎn)x1
const x1 = i * barWidth + width / 2
// 繪制點(diǎn)x2
const x2 = width / 2 - (i + 1) * barWidth
// 繪制右半部分波形圖
con.fillRect(x1, y, barWidth - 2, barHeight)
// 繪制左半部分波形圖
con.fillRect(x2, y, barWidth - 2, barHeight)
}
})()
</script>
</body>
</html>到此這篇關(guān)于JavaScript+Canvas實(shí)現(xiàn)繪制音頻可視化波形圖的文章就介紹到這了,更多相關(guān)JavaScript Canvas音頻波形圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中break、continue和return的用法區(qū)別實(shí)例分析
這篇文章主要介紹了JavaScript中break、continue和return的用法區(qū)別,結(jié)合實(shí)例形式詳細(xì)對(duì)比分析了JavaScript中break、continue和return的基本功能、使用方法、區(qū)別與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
JavaScript手寫源碼之實(shí)現(xiàn)arrify轉(zhuǎn)數(shù)組
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)arrify轉(zhuǎn)數(shù)組,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaScript有一點(diǎn)的幫助,需要的可以參考一下2023-02-02
小程序?qū)崿F(xiàn)按下錄音松開識(shí)別語音
這篇文章主要為大家詳細(xì)介紹了小程序?qū)崿F(xiàn)按下錄音松開識(shí)別語音,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
用JavaScript實(shí)現(xiàn)讓瀏覽器停止載入頁面的方法
下面小編就為大家?guī)硪黄肑avaScript實(shí)現(xiàn)讓瀏覽器停止載入頁面的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01
前端JavaScript?6?種主流接口請(qǐng)求技術(shù)全解
這篇文章主要介紹了前端JavaScript?6?種主流接口請(qǐng)求技術(shù)的相關(guān)資料,包括XMLHttpRequest、FetchAPI、Axios、jQueryAjax、WebSocket和GraphQL,并提供了每種方案的基礎(chǔ)用法、高級(jí)配置、優(yōu)點(diǎn)、缺點(diǎn)及適用場(chǎng)景,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03
微信小程序 拍照或從相冊(cè)選取圖片上傳代碼實(shí)例
這篇文章主要介紹了微信小程序 拍照或從相冊(cè)選取圖片上傳代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08

