Смена изображения в зависимости от показателя громкости микрофона
У меня есть 100 кадров которые должны меняться подобно анимации отталкиваясь от значения громкости микрофона.
Пробовал с помощью JS, использовал for для всех фотографий и через createElement хотел что бы они заменяли друг-друга. Не удалось подключить анализатор (нашел частотный анализатор но не dB).
Подскажите как бы мне сделать подобное и не проще ли использовать C++ для подобного (хочу использовать как плагин для OBS)
Ответы (1 шт):
Пишете, что кадры должны менять друг друга в зависимости от значений амплитуды сигнала с микрофона и при этом хотите использовать анализатор. Но в этом случае больше подойдёт createMediaStreamSource():
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Визуализатор</title>
</head>
<body>
<center><h1>Визуализатор</h1>
<button onclick="start(); this.disabled = true"> Старт </button><br /><br />
<img id=myimg />
<br /><br />
<div id=mydiv></div>
<script>
var sensitivity = 10 // во сколько раз нужно поднять чувствительность
function start(){
var db = 4096; // длина буфера чтения со входа звуковой карты
audioCtx = new AudioContext;
navigator.getUserMedia({audio: true}, function(stream){
var source = audioCtx.createMediaStreamSource(stream);
source.node = source.context.createScriptProcessor.call(source.context, db, 1);
source.node.onaudioprocess = function(e){
var index = Math.min(Math.floor(Math.abs(100 * e.inputBuffer.getChannelData(0)[0] * sensitivity)), 99);
mydiv.innerText = index;
myimg.src = "kadr" + index + ".png"
}
source.connect(source.node);
source.node.connect(source.context.destination);
}, function(){alert("Что-то пошло не так")});
}
</script>
</body>
</html>
Этот пример работает на локалке, локальном сервере и на хостинге https. Но если хотите использовать анализатор, то тогда изображениям лучше выстроиться в ряд, и чтобы высота каждого кадра менялась синхронно значению соответствующей частоты:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Анализатор</title>
<style>
img{
border-style: solid;
border-width: 1px;
position: absolute;
height: 128px;
width: 6px;
top: 120px;
}
</style>
</head>
<body>
<center><h1>Анализатор</h1>
<button onclick="start(); this.disabled = true"> Старт </button>
<script>
var num = 128, // количество частотных полос
steep = 8; // шаг между полосами в пикселях
for(i = 0; i < 128; i ++){
var kadr = document.createElement("img");
kadr.id = "k" + i;
kadr.src = "kadr" + i + ".png";
kadr.style.left = i * steep + "px";
document.body.appendChild(kadr);
}
function start(){
audioCtx = new AudioContext;
navigator.getUserMedia({audio: true}, function(stream){
var source = audioCtx.createMediaStreamSource(stream);
analyser = audioCtx.createAnalyser();
analyser.fftSize = num * 2;
source.connect(analyser);
// analyser.connect(audioCtx.destination); // Только если нужно через динамики слушать звук с микрофона
var frequencyData = new Uint8Array(analyser.frequencyBinCount);
setInterval(function(){
analyser.getByteFrequencyData(frequencyData); // Записываем в массив данные уровней частот
for(i = 0; i < num; i ++) document.getElementById("k" + i).style.height = frequencyData[i] + "px";
}, 20);
}, function(){alert("Что-то пошло не так")});
}
</script>
</body>
</html>
Имена графических файлов с кадрами в обоих примерах должны быть формата "kadr35.png", где скажем 35 - это порядковый номер кадра, начиная с ноля.