HTML5 Audio становится громче после паузы и воспроизведения - PullRequest
0 голосов
/ 30 мая 2018

Я делаю аудиоплеер с JavaScript, все работает нормально, пока я не добавлю звуковой визуализатор.Когда я приостанавливаю песню, а затем снова ее запускаю, звук становится громче с каждым разом, пока он не искажается.

Я новичок в HTML5 Audio API, я попытался установитьгромкость как фиксированное значение, но не работает.

Код визуализатора это:

function visualizer(audio) {
    let context = new AudioContext();

    const gainNode = context.createGain();
    gainNode.gain.value = 1; // setting it to 100%
    gainNode.connect(context.destination);

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

    let canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    let ctx = canvas.getContext("2d");

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

    analyser.fftSize = 2048;

    let bufferLength = analyser.frequencyBinCount;

    let dataArray = new Uint8Array(bufferLength);

    let WIDTH = ctx.canvas.width;
    let HEIGHT = ctx.canvas.height;

    let barWidth = (WIDTH / bufferLength) * 1.5;
    let barHeight;
    let x = 0;

    let color = randomColor();

    function renderFrame() {
      requestAnimationFrame(renderFrame);
      x = 0;
      analyser.getByteFrequencyData(dataArray);
      ctx.clearRect(0, 0, WIDTH, HEIGHT);

      for (let i = 0; i < bufferLength; i++) {
        barHeight = dataArray[i];

        ctx.fillStyle = color;
        ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
        x += barWidth + 1;

      }
    }

    musicPlay();
    renderFrame();
  }

И:

  function musicPlay() {
    status = 'playing';
    audio.play();
  }

Итак, я не знаюесли я делаю что-то не так с аудиоанализатором, я пытался создать глобальный контекст и не делать new AudioContext(); каждый раз, когда я вхожу в функцию, также я пытался указать фиксированную громкость с помощью:

audio.volume = 1; 

или с GainNode, как вы можете видеть на функции, но она не работает.

Где моя ошибка и почему звук становится громче?

С уважением!

--- Обновление 1 ---

Звук загружается с URL:

function loadAudioElement(url) {
    return new Promise(function (resolve, reject) {
      let audio = new Audio();
      audio.addEventListener('canplay', function () {
        /* Resolve the promise, passing through the element. */
        resolve(audio);
      });
      /* Reject the promise on an error. */
      audio.addEventListener('error', reject);
      audio.src = url;
    });
  }

И на моем плеере у меня есть:

let playButtonFunction = function () {
      if (playstatus === 'pause') {
        loadAudioElement(audio.src).then(
          visualizer(audio)
        );
      } else if (playstatus === 'playing') {
        musicPause();
      }
    };

1 Ответ

0 голосов
/ 31 мая 2018

Ну, как указывало Get Off My Lawn , я по ошибке добавил несколько аудиоэлементов.

Решением было использование кода загрузки песни вне функции playButtonFunction и только сделать:

let playButtonFunction = function () {
      if (playstatus === 'pause') {
        musicPlay();
      } else if (playstatus === 'playing') {
        musicPause();
      }
    };

Но у меня все еще была одна проблема с функциями next / previous .В этих случаях мне нужно вызвать функцию loadAudioElement, потому что песня меняется (когда вы нажимаете кнопку воспроизведения / паузы нет, это та же самая песня), но с этим у меня снова та же проблема.

Что ж, послеНемного покопавшись, я обнаружил, что если вы хотите постоянно воспроизводить плейлист и визуализировать музыку, ВЫ ДОЛЖНЫ ВЫПУСТИТЬ СТАРЫЙ КОНТЕКСТ ПЕРЕД ЗАГРУЗКОЙ НОВОЙ ПЕСНИ .Не только во избежание увеличения громкости песни, процессор и память также будут увеличиваться после 3-4 песен, и браузер начнет медленно работать в зависимости от машины.Итак:

1 - я создал глобальную переменную с именем clearContextAudio = false;

2 - к моим следующим / предыдущим функциям я добавил этот код:

if (closeAudioContext) { //MANDATORY RELEASE THE PREVIOUS RESOURCES TO AVOID OBJECT OVERLAPPING AND CPU-MEMORY USE
      context.close();
      context = new AudioContext();
}
loadAudioElement(audio.src).then(
   visualizer(audio)
);

3 - В моей функции visualizer(audio) я изменил:

let context = new AudioContext();

на

closeAudioContext = true; //MANDATORY RELEASE THE PREVIOUS RESOURCES TO AVOID OBJECT OVERLAPPING AND CPU-MEMORY USE

Значение, которое инициализируется как false, поскольку в первый раз не воспроизводится песня, ипосле воспроизведения песни вам всегда нужно будет освободить старые ресурсы, поэтому для переменной всегда будет установлено значение true.Теперь вы можете пропустить все моменты, когда вам нужна песня, и не беспокоиться о памяти и проблемах с перекрытием.

Надеюсь, что это поможет кому-то другому пытаться достичь того же самого!Привет!

...