进来,我教你拿到音频的频率!可以做图表和好玩的!

177 阅读6分钟

在数字世界的海洋中,SharkChili是一名孤独的探险家,他的现实生活就像他编写的代码一样,充满了逻辑和规律,却缺少了一丝温暖和色彩。作为一名程序员,他的日常充斥着无尽的代码和咖啡的苦涩。然而,他的生活因为一次偶然的邂逅而彻底改变。 那是一个阳光明媚的下午,SharkChili在公园的长椅上享受着难得的闲暇时光。他的目光被一位女孩吸引,她坐在不远处的草地上,耳机里流淌出轻柔的旋律,脸上洋溢着幸福的微笑。SharkChili被这画面深深吸引,他鼓起勇气,走了过去。

“嗨,不介意我坐在这里吧?”SharkChili的声音有些颤抖。

女孩抬起头,露出了灿烂的笑容,“当然不介意,这里可是公共区域。”

他们聊了起来,从音乐到电影,从书籍到梦想。SharkChili发现,这个名叫苏菲的女孩,不仅有着甜美的笑容,还有着对音乐的深刻理解和热爱。他们的话题很快就转到了音乐上,苏菲提到了她最喜欢的一个音乐平台,但是上面的音乐都需要付费。

“如果有一个免费的API,可以获取这些音乐就好了。”苏菲半开玩笑地说。

这句话像一道闪电击中了SharkChili,他的眼睛亮了起来。作为一名程序员,他知道这并非不可能。他决定,要为苏菲,也为自己,找到这样一个API。

几天后,SharkChili开始了他的探索之旅。他深入网络的每一个角落,寻找着可能的线索。夜以继日,他的眼睛因为长时间盯着屏幕而变得通红,但他的心中充满了激情和决心。

终于,在一个被遗忘的论坛帖子中,他发现了一个链接。点击进去,是一个古老的API文档,它能够访问一个庞大的音乐数据库。SharkChili的心跳加速,他知道,这就是他要找的东西。

他开始编写代码,将这个API集成到一个特殊的项目中。他不仅仅是想要获取音乐,而是想要创造一些特别的东西——一种全新的图表和特效,它们能够随着音乐的节奏和情感变化而变化,为用户带来前所未有的视觉体验。

SharkChili的手指在键盘上飞快地舞动,每一行代码都像是音符,编织成一首独特的交响乐。他创造了一个图表,它能够根据音乐的节奏变化颜色和形状,就像一个活着的生物,随着音乐的起伏而呼吸。他还设计了特效,它们能够根据音乐的情感强度变化,从柔和的渐变到激烈的爆炸,每一种效果都与音乐完美同步。

经过无数次的测试和修改,一个能够随着音乐变化的图表和特效库诞生了。他兴奋地将这个项目展示给苏菲,她的眼睛里闪烁着惊喜和赞赏。

“这太不可思议了!”苏菲惊叹道。

随着时间的推移,SharkChili的项目开始在设计师和开发者中传播开来。人们惊叹于它的创新和强大,SharkChili也因此获得了巨大的成功。他不仅赢得了苏菲的心,也走上了人生的巅峰。

他们一起坐在公园的长椅上,看着从SharkChili的特效库中流出的美妙图案。SharkChili知道,这一切都始于那个阳光明媚的下午,始于一段美丽的爱情故事。

脑子里面就想编一段,没办法。。。

上干货喽!

getByteFrequencyData 一个可以获取频谱的Web Api

AnalyserNode接口的 getByteFrequencyData()  方法将当前频率数据复制到传入的 Uint8Array(无符号字节数组)中。

如果数组的长度小于 AnalyserNode.frequencyBinCount, 那么 Analyser 多出的元素会被删除。如果是大于,那么数组多余的元素会被忽略。

获取后的数组里面是多个对象,键是对应的索引,值就是音频的响度了

就是下面图片中的死样子

image.png

展示一下全部代码,很简单

// 创建一个新的 AudioContext 实例
const audioContext = new AudioContext();

// 加载音频文件
const audioLoader = new THREE.AudioLoader();
let audioBuffer;

audioLoader.load("./huahai.mp3", function (buffer) {
  audioBuffer = buffer;
  const audioSource = audioContext.createBufferSource(); // 创建一个新的音频源节点
  audioSource.buffer = buffer; // 设置音频源的缓冲区为加载的音频文件
  audioSource.connect(audioContext.destination); // 将音频源连接到输出(扬声器)
  audioSource.start(); // 开始播放音频

  // 创建一个 AnalyserNode 节点
  const analyser = audioContext.createAnalyser();
  analyser.fftSize = 2048; // 设置 FFT 大小

  // 将音频源连接到 AnalyserNode
  audioSource.connect(analyser);
  analyser.connect(audioContext.destination);

  // 创建一个 Uint8Array 来存储频率数据
  const bufferLength = analyser.frequencyBinCount;
  const dataArray = new Uint8Array(bufferLength);

  // 定期获取频率数据
  function update() {
    analyser.getByteFrequencyData(dataArray);

    // 在控制台打印频率数据
    console.log(dataArray);

    // 可以在这里添加你的代码来使用频率数据,例如创建可视化效果

    requestAnimationFrame(update); // 循环调用 update 函数
  }

  update(); // 启动循环
});

// 错误处理
audioLoader.onError = function (event) {
  console.error("Error loading audio file:", event);
};


  1. 友情提示:提示web api 需要在浏览器中打开这个js文件,例如我的上文js文件名叫audioContext
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="./audioContext.js"></script>
  </body>
</html>

  1. 友情提示:用html文件做药引子,然后打开服务就可以了,记得自己更换文件路径哦,引入three的cdn就行了

大家都已经会了对吧,那么做个频率表格吧

先看效果

pinlv-ezgif.com-video-to-gif-converter.gif

不废话直接展示代码,用的echarts展示

        var option = {
          xAxis: {
            type: "category", 
            data: Object.keys(analyser.data).map(function (key) {
              return key; // 这里使用数据项的键作为x轴的标签
            }),
            axisLine: {
              show: false, // 不显示Y轴线
            },
            axisTick: {
              show: false, // 不显示Y轴刻度
            },
            axisLabel: {
              show: false, // 不显示Y轴标签
            },
            splitLine: {
              show: false, // 取消Y轴网格线
            },
            axisPointer: {
              // 控制X轴箭头线
              show: false,
            },
          },
          yAxis: {
            axisLine: {
              show: false, // 不显示Y轴线
            },
            axisTick: {
              show: false, // 不显示Y轴刻度
            },
            axisLabel: {
              show: false, // 不显示Y轴标签
            },
            splitLine: {
              show: false, // 取消Y轴网格线
            },
          },

          visualMap: {
            top: -10050,
            right: -100010,
            pieces: [
              {
                gt: 0,
                lte: 50,
                color: "#93CE07",
              },
              {
                gt: 50,
                lte: 100,
                color: "#FBDB0F",
              },
              {
                gt: 100,
                lte: 150,
                color: "#FC7D02",
              },
              {
                gt: 150,
                lte: 200,
                color: "#FD0100",
              },
              {
                gt: 200,
                lte: 300,
                color: "#AA069F",
              },
              {
                gt: 300,
                color: "#AC3B2A",
              },
            ],
            outOfRange: {
              color: "#999",
            },
          },
          series: {
            type: "line", // 指定图表类型为折线图
            data: Object.values(analyser.data),
            smooth: true,
          },
        };

再来一个结合three的效果吧

20250102_143952-ezgif.com-video-to-gif-converter.gif

写掘金的小伙伴是不是想上传视频,但是觉得麻烦呢

https://ezgif.com/video-to-gif 去吧,使用这个网址把视频转成动态图,复制粘贴到文章内就行了哦