Отображение анимированной синусоиды с помощью AudioContext и холста

Поэтому, чтобы все было просто и честно, я пытаюсь использовать AudioContext вместе с холстом для отображения анимированной синусоиды в соответствии с песней, которая сейчас воспроизводится на веб-странице. Я начал с кода из Voice-change-o-matic (его легко найти на GitHub и является общественным достоянием) и удалил все, что было лишним для моей цели, а также изменил некоторые строки:

// set up canvas context for visualizer
var canvas = document.querySelector('.visualizer');
var canvasCtx = canvas.getContext("2d");

var intendedWidth = document.querySelector('.wrapper').clientWidth;

canvas.setAttribute('width',intendedWidth);

var visualSelect = document.getElementById("visual");

var drawVisual;

// set up forked web audio context, for multiple browsers
// window. is needed otherwise Safari explodes

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();

//set up the different audio nodes we will use for the app

var analyser = audioCtx.createAnalyser();
analyser.minDecibels = -90;
analyser.maxDecibels = -10;
analyser.smoothingTimeConstant = 0.85;

// grab audio track via XHR for convolver node

var soundSource = audioCtx.createBufferSource();

ajaxRequest = new XMLHttpRequest();

ajaxRequest.open('GET', 'https://mdn.github.io/voice-change-o-matic/audio/concert-crowd.ogg', true);

ajaxRequest.responseType = 'arraybuffer';


ajaxRequest.onload = function() {
  var audioData = ajaxRequest.response;

  audioCtx.decodeAudioData(audioData, function(buffer) {
      soundSource = buffer;
    }, function(e){ console.info("Error with decoding audio data" + e.err);});
};

ajaxRequest.send();

playSound();

function playSound(buffer){
    var source = audioCtx.createBufferSource();
    source.buffer = buffer;

    soundSource.connect(analyser);
    analyser.connect(audioCtx.destination);
    soundSource.start();
    visualize();
}

// set up canvas context for visualizer

function visualize() {
  WIDTH = canvas.width;
  HEIGHT = canvas.height;

    analyser.fftSize = 2048;
    var bufferLength = analyser.fftSize;
    console.info(bufferLength);
    var dataArray = new Uint8Array(bufferLength);

    canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

    var draw = function() {

      drawVisual = requestAnimationFrame(draw);

      analyser.getByteTimeDomainData(dataArray);

      canvasCtx.fillStyle = 'rgb(200, 200, 200)';
      canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

      canvasCtx.lineWidth = 2;
      canvasCtx.strokeStyle = 'rgb(20, 120, 60)';

      canvasCtx.beginPath();

      var sliceWidth = WIDTH * 1.0 / bufferLength;
      var x = 0;

      for(var i = 0; i < bufferLength; i++) {

        var v = dataArray[i] / 128.0;
        var y = v * HEIGHT/2;

        if (i === 0) {
          canvasCtx.moveTo(x, y);
        } else {
          canvasCtx.lineTo(x, y);
        }

        x += sliceWidth;
      }

      canvasCtx.lineTo(canvas.width, canvas.height/2);
      canvasCtx.stroke();
    };

    draw();
}

Очевидно, что код не работает, и после нескольких часов работы над этим у меня просто нет идей. При запуске код не выдает ошибок и холст прорисовывается, но музыки не слышно, и линия, которая должна быть синусоидой, остается неподвижной. Кто-нибудь видит, что мне не хватает?

Заранее спасибо за помощь!

Этот пример MDN очень похож на ваш код!
vrintle 27.10.2018 08:35

Ваш playSound ожидает AudioBuffer, который будет доступен только после срабатывания обратного вызова decodeAudioData, который сам вызывается только в xhr.onload. Возможно, вы захотите немного прочитать о работе с асинхронным кодом в js. Для исправления просто вызовите playSound (buffer) из обратного вызова decodeAudioData.

Kaiido 27.10.2018 08:54

Большое спасибо за исправление @Kaiido, это помогло! Я признаю, что у меня нет такого большого опыта работы с асинхронным кодом, и прислушусь к вашему совету, чтобы изучить его подробнее!

Phil Thibeault 27.10.2018 19:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
23
0

Другие вопросы по теме