在数字世界的海洋中,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 多出的元素会被删除。如果是大于,那么数组多余的元素会被忽略。
获取后的数组里面是多个对象,键是对应的索引,值就是音频的响度了
就是下面图片中的死样子
展示一下全部代码,很简单
// 创建一个新的 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);
};
- 友情提示:提示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>
- 友情提示:用html文件做药引子,然后打开服务就可以了,记得自己更换文件路径哦,引入three的cdn就行了
大家都已经会了对吧,那么做个频率表格吧
先看效果
不废话直接展示代码,用的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的效果吧
写掘金的小伙伴是不是想上传视频,但是觉得麻烦呢
https://ezgif.com/video-to-gif去吧,使用这个网址把视频转成动态图,复制粘贴到文章内就行了哦