gpt4 book ai didi

javascript - 如何在 Javascript 中使用 Web Audio API 更改 CSS 参数?

转载 作者:行者123 更新时间:2023-12-02 20:53:04 25 4
gpt4 key购买 nike

我正在从事一个音乐可视化元素。

在我的 HTML 页面上,我有一个使用 CSS 将样式设置为黄色圆圈的 div。

使用 JAVASCRIPT,我想收集音频文件的频率数据,并使用该数据,每当频率达到特定数字时将圆圈的颜色更改为粉红色 - 该数字将代表音频中的 transient 。基本上,一个黄色圆圈随着歌曲的节拍变成粉红色。

HTML:

<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8">
<title>CSS Flower</title>
<style>
/* centering */
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}

/* proportion and perspective */
#scene {
width: 200px;
height: 200px;
perspective: 600px;
perspective-origin: center top;
}

.flower {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
}

#center {
position: absolute;
width: 100px;
height: 100px;
border-radius: 50px;
background: yellow; // THIS IS YELLOW CIRCLE, AND PARAMETER I WANT TO CHANGE
transform: rotateX(180deg) translateX(50px) translateZ(-140px);
}

</style>
</head>

<body>
<input type="file" id="file-input" accept="audio/*,video/*,image/*" />
<canvas id="canvas"></canvas>
<div id="scene">
<div class="flower">
<div class="center" id="center"></div>
</div>
</div>
<audio id="audio" controls></audio>
<script src="audio.js"></script>
</body>
</html>

我现在拥有的JS代码:

window.onload = function() {

const file = document.getElementById("file-input");
const canvas = document.getElementById("canvas");
const audio = document.getElementById("audio");

file.onchange = function() {

const files = this.files;
console.log('FILES[0]: ', files[0])
audio.src = URL.createObjectURL(files[0]);

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext("2d");
const flower = document.getElementById('center');



const context = new AudioContext();
let src = context.createMediaElementSource(audio);
const analyser = context.createAnalyser();

src.connect(analyser);
analyser.connect(context.destination);

analyser.fftSize = 1024;

const bufferLength = analyser.frequencyBinCount;

const dataArray = new Uint8Array(bufferLength);

const WIDTH = canvas.width;
const HEIGHT = canvas.height;

function renderFrame() {
requestAnimationFrame(renderFrame); // Takes callback function to invoke before rendering


analyser.getByteFrequencyData(dataArray); // Copies the frequency data into dataArray
// Results in a normalized array of values between 0 and 255
// Before this step, dataArray's values are all zeros (but with length of 8192)

for (let i = 0; i < bufferLength; i++) {
console.log("data array: ", dataArray)

//from here I can see the different frequencies collected in the array, but I don't know how to proceed
}

audio.play();
renderFrame();
};
};
};

我不知道如何制定 FOR 循环,以及如何将此信息与 CSS 参数连接起来。

任何帮助将不胜感激!几天来我一直在试图弄清楚,但没有成功。正如您可能从我的代码中看出的那样,我是一个完全的初学者!

祝一切顺利,

Jade

最佳答案

只需对频率进行平均即可。这是工作示例:

const file = document.getElementById("file-input");
const canvas = document.getElementById("canvas");
const audio = document.getElementById("audio");

var threshold = 230; //Point where turn the "flower" pink
var frequencies = 10; //Number of records to count (You want to look for lower frequencies)

file.onchange = function() {

const files = this.files;
//console.log('FILES[0]: ', files[0])
audio.src = URL.createObjectURL(files[0]);

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext("2d");
const flower = document.getElementById('center');



const context = new AudioContext();
let src = context.createMediaElementSource(audio);
const analyser = context.createAnalyser();

src.connect(analyser);
analyser.connect(context.destination);

analyser.fftSize = 1024;

const bufferLength = analyser.frequencyBinCount;

const dataArray = new Uint8Array(bufferLength);

const WIDTH = canvas.width;
const HEIGHT = canvas.height;

function renderFrame() {
requestAnimationFrame(renderFrame); // Takes callback function to invoke before rendering


analyser.getByteFrequencyData(dataArray); // Copies the frequency data into dataArray
// Results in a normalized array of values between 0 and 255
// Before this step, dataArray's values are all zeros (but with length of 8192)

let sum = 0;

for(let i = 0; i < bufferLength; i++) {
if(i < frequencies) sum += dataArray[i];

//Do some other stuff
}

//Change CSS according to threshold
let avg = sum / frequencies;
flower.style.backgroundColor = avg > threshold ? "pink" : "yellow";
flower.style.transform = `scale(${avg / 255})`;
flower.innerText = ~~avg;

};

//!!This functions have to be called outside of the rendering function (renderFrame)!!
audio.play();
renderFrame();
};


/* Sliders */
const sliderF = document.querySelector(".slider.f");
const sliderFvalue = document.querySelector(".slider-value.f");
const sliderT = document.querySelector(".slider.t");
const sliderTvalue = document.querySelector(".slider-value.t");

sliderF.oninput = function() {
sliderFvalue.innerText = this.value;
frequencies = +this.value;
}

sliderT.oninput = function() {
sliderTvalue.innerText = this.value;
threshold = +this.value;
}
/* centering */
body {
margin: 0;
}

canvas {
position: absolute;
pointer-events: none;
}

#audio {
width: 100vw;
}

#center {
width: 100px;
height: 100px;
border-radius: 50px;
background-color: yellow;
text-align: center;
line-height: 100px;
}

.slider-value {
display: inline-block;
width: 25px;
}

.slider {
width: 90vw;
}
<input type="file" id="file-input" accept="audio/*,video/*,image/*" /><br>
<canvas id="canvas"></canvas>
<audio id="audio" controls></audio>
<div class="center" id="center"></div>

<!-- Frequences Slider --->
<input type="range" min="0" max="500" value="10" step="1" class="slider f">
<span class="slider-value f">10</span>

<!-- Threshold Slider --->
<input type="range" min="0" max="255" value="230" step="1" class="slider t">
<span class="slider-value t">230</span>

您只需要调整 slider 即可使其完美,但最好使用一些低通均衡器,这样您会得到更接近的结果。

关于javascript - 如何在 Javascript 中使用 Web Audio API 更改 CSS 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61560792/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com