Смена изображения в зависимости от показателя громкости микрофона

У меня есть 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 - это порядковый номер кадра, начиная с ноля.

→ Ссылка