tyoma_koder
@tyoma_koder

Как получить график громкости аудио без его воспроизведения?

new AudioContext насколько я понял работает только во время воспроизведения аудио, есть какой то способ получить данные о громкости звука в зависимости от времени без jquery и кликов на скрытый тег audio? Может это можно как то в php сделать
  • Вопрос задан
  • 73 просмотра
Пригласить эксперта
Ответы на вопрос 2
Okujava-script
@Okujava-script
Веб-программист с абсолютным слухом и композитор
Декодирование аудиоданных из аудиофайла с помощью WebAudio Api можно действительно делать без воспроизведения этого файла. А это значит, что это может происходить по ходу загрузки страницы, и клики при этом не нужны.
<html>
<head>
<meta charset="utf-8">
<title>Визуализатор</title>
<style>
#canvas{
    position: absolute;
    top: 50px;
    left: 0px;
    background: #333;
}
#progress{
    position: absolute;
    top: 50px;
    left: 0px;
    background: rgba(255, 155, 0, 0.5);
    width: 0px;
    height: 256px;
}
</style>
</head>
<body bgcolor=#444>
<audio id=audio src="sound.mp3" controls></audio>
<canvas id=canvas width=512 height=256></canvas>
<div id=progress></div>
<script>
var audio = document.getElementById("audio");
var ctx = canvas.getContext("2d");
var color_L = "#7cf", color_R = "#f7c"; // Цвета осциллограмм левого и правого стереоканалов
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
audio.onplay = function(){b = setInterval(function(){progress.style.width = Math.floor(audio.currentTime / audio.duration * canvas.width) + "px"}, 100)};
audio.onended = function(){ 
    this.currentTime = 0;
    clearInterval(b);
    progress.style.width = "0px";
}
var source = audioCtx.createBufferSource();
var request = new XMLHttpRequest();
request.open('GET', audio.src, true);
request.responseType = 'arraybuffer';
request.onload = function(){
    var audioData = request.response;
    audioCtx.decodeAudioData(audioData, function(buffer){
        source.buffer = buffer;
        data_L = buffer.getChannelData(0);
        data_R = buffer.getChannelData(1); // Если аудиофайл моно - поменяйте в этой сроке единицу на ноль.
         // При несоответствии количества стереоканалов - ошибка в консоли и код не работает.
        for(var i = 0; i < data_L.length; i++){
            var x = Math.floor(i / data_L.length * canvas.width);
            var L = data_L[i] * canvas.height / 4;
            var R = data_R[i] * canvas.height / 4;
            if(Math.floor(i / 16) == i / 16){ // Число 16 для больших аудиофайлов лучше побольше. Нужно подбирать.
                ctx.fillStyle = color_L;
                ctx.fillRect(x, canvas.height * 0.25 + L, 1, -L);
                ctx.fillStyle = color_R;
                ctx.fillRect(x, canvas.height * 0.75 + R, 1, -R);
            }
        }
    },
    function(e){"Error with decoding audio data" + e.err});
}
request.send();
canvas.onmousedown = progress.onmousedown = function(e){
    progress.style.width = e.pageX + "px";
    audio.currentTime = e.pageX / canvas.width * audio.duration;
}
canvas.ondblclick = function(){audio.play()};
ctx.fillStyle = color_L;
ctx.fillRect(0, canvas.height * 0.25, canvas.width, 1);
ctx.fillStyle = color_R;
ctx.fillRect(0, canvas.height * 0.75, canvas.width, 1);
</script>
</body>
</html>
62bb7dc72e0ba998610708.jpeg
Ответ написан
Комментировать
DanArst
@DanArst Куратор тега JavaScript
Гриффиндор в моде при любой погоде!
Вот, как вариант, раз вы хотите делать это не во фронте. Не знаю насколько актуально. На выходе вы получите png-картинку
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы