javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > canvas音乐频谱

使用canvas绘图音乐频谱示例及技术分析

作者:smallStone

这篇文章主要为大家介绍了使用canvas实现音乐频谱示例及技术分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

看到跳动的音符你难道不想知道它是如何实现的么?开撸!

问:实现这个有什么用呢?

答:装杯用!😥其实这个操作能实现音频效果器。就是主播开麦后大妈声音变成少女,男人声音可以变女声!😱因为音频分析器可以拿到音频的频谱,既可以改变音调啊音色啊什么的就可以实现音频效果器!🐷

不想看我啰嗦的直接看最后,有整体html+js代码,粘贴到你的html页面内,换以下音频资源链接就能看到效果了!

效果图

技术分析

音频加载

html内增加audio标签。将音乐加载进来。给audio标签增加controls属性用来控制音乐播放。如下:

<html>
<body>
 <audio src="/source/YOU.m4a" controls></audio>
</body>
</html>

频谱获取

要获取音频的频谱需要使用javascriptAudioContext对象。

var audio = document.querySelector("audio");
let dataArray = new Uint8Array(512);
let analyser = null
 audio.onplay = function() {
     let audctx = new AudioContext() // 创建音频上下文
        let source = audctx.createMediaElementSource(audio) // 创建音频源
        analyser = audctx.createAnalyser() // 创建音频分析器
        analyser.fftSize = 512 // 设置分析器大小, 必须为2^n次方
        // 创建一个数组,用于存放分析器节点数据
        // analyser.frequencyBinCount可以拿到傅里叶变换的值,因为傅里叶变换是对称的因此只要一半即可(傅里叶变换请自行搜索)
        dataArray = new Uint8Array(analyser.frequencyBinCount)
        source.connect(analyser) // 音频源连接到音频分析器
        analyser.connect(audctx.destination) // 音频分析器连接到音频输出
}

至此我们已经获取到了音频的频谱数据。

频谱可视化

对于高效绘制需要用到画布,既canvas标签,在body内增加canvas标签,并起idcvs

<body>
    <canvas  id="cvs"></canvas>
    <audio src="/source/YOU.m4a" controls></audio>
</body>
var cvs = document.getElementById("cvs");
var ctx = cvs.getContext("2d");
function initCanvas() {
    // 设置canvas宽度为浏览器可视区域
    cvs.width = window.innerWidth * devicePixelRatio;
    // 设置canvas高度为浏览器可视区域的一半
    cvs.height = window.innerHeight / 2 * devicePixelRatio;
}
// 窗口变化时候重新设置canvas宽高
window.onresize = function() {
    initCanvas();
}
// 定义draw方法用于绘制频谱
function draw() {
    // 使用浏览器自带帧动画函数实现每一帧都绘制。
    requestAnimationFrame(draw);
    // 清空画布
    ctx.clearRect(0, 0, cvs.width, cvs.height);
    const len = dataArray.length / 1.2; // 截取频谱绘制长度
    const barWidth = cvs.width / len;  // 每一根柱子的宽度
    ctx.fillStyle = '#c875fc'; // 给柱子填充颜色
    // 遍历每一根柱子,设置其位置以及边框。
    for (let i = 0; i < len; i++) {
        const data = dataArray[i]
        const barHeight = data / 255 * cvs.height
        const x = i * barWidth
        const y = cvs.height - barHeight
        drawBorder(x,y,barWidth, barHeight)
        ctx.fillStyle = '#8ca86d'
        ctx.fillRect(x, y, barWidth, barHeight)
    }
}

至此基本完成了绘制方面的任务

全部合并后就是以下代码,将以下代码在你本机创建一个html复制进去就可以看到效果(注意把音频资源换成自己的):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>声音波浪</title>
</head>
<style>
#cvs {
    border: 1px solid #000;
}
audio {
    display: block;
}
</style>
<body>
<canvas  id="cvs"></canvas>
<audio src="/source/YOU.m4a" controls></audio>
</body>
<script>
var cvs = document.getElementById("cvs");
var ctx = cvs.getContext("2d");
var audio = document.querySelector("audio");
let isInitAudio = false;
let analyser = null
let dataArray = new Uint8Array(512);
/* 初始化canvas */
function initCanvas() {
    cvs.width = window.innerWidth * devicePixelRatio;
    cvs.height = window.innerHeight / 2 * devicePixelRatio;
}
window.onresize = function() {
    initCanvas();
}
/* 初始化音频 */
function initAudio() {
    audio.onplay = function() {
        let audctx = new AudioContext() // 创建音频上下文
        let source = audctx.createMediaElementSource(audio) // 创建音频源
        analyser = audctx.createAnalyser() // 创建音频分析器
        analyser.fftSize = 512 // 设置分析器大小, 必须为2^n次方
        // 创建一个数组,用于存放分析器节点数据
        // analyser.frequencyBinCount可以拿到傅里叶变换的值,因为傅里叶变换是对称的因此只要一半即可
        dataArray = new Uint8Array(analyser.frequencyBinCount)
        draw()
        source.connect(analyser) // 音频源连接到音频分析器
        analyser.connect(audctx.destination) // 音频分析器连接到音频输出
        let bufferLength = analyser.frequencyBinCount
    }
}
function draw() {
    requestAnimationFrame(draw);
    // 清空画布
    ctx.clearRect(0, 0, cvs.width, cvs.height);
    analyser.getByteFrequencyData(dataArray)
    const len = dataArray.length / 1.2
    const barWidth = cvs.width / len
    ctx.fillStyle = '#c875fc'
    for (let i = 0; i < len; i++) {
        const data = dataArray[i]
        const barHeight = data / 255 * cvs.height
        const x = i * barWidth
        const y = cvs.height - barHeight
        drawBorder(x,y,barWidth, barHeight)
        ctx.fillStyle = '#8ca86d'
        ctx.fillRect(x, y, barWidth, barHeight)
    }
}
function drawBorder(xPos, yPos, width, height, thickness = 1) {
    ctx.fillStyle='#000';
    ctx.fillRect(xPos - (thickness), yPos - (thickness), width + (thickness * 2), height + (thickness * 2));
}
function initAll() {
    initCanvas();
    initAudio()
}
initAll()
</script>
</html>

以上就是使用canvas实现音乐频谱示例及技术分析的详细内容,更多关于canvas音乐频谱的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文