暂停然后再次播放后,HTML5音频会变得更响亮

时间:2018-05-30 20:17:34

标签: javascript html5-audio audio-player

我正在使用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 ---

从网址加载的音频:

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 :(得分:0)

好吧,正如脱掉我的草坪指出的那样,我错误地添加了多个音频元素。

解决方案是在 playButtonFunction 之外加载歌曲的代码并且只执行:

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

但我仍有一个问题, next / previous 功能。在这些情况下,我需要调用loadAudioElement函数,因为歌曲正在改变(当你按播放/暂停不播放时,它是同一首歌)但是这样我再次遇到同样的问题。

好吧,经过一番挖掘,我发现如果你想播放一个播放列表并一直想象音乐,你必须在加载新歌之前释放旧的背景。不仅为了避免增加歌曲音量,在3-4首歌曲之后cpu和内存也会增加,并且浏览器将根据机器开始慢慢运行。所以:

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。现在,您可以跳过您想要一首歌的所有时间,而不是关注内存和重叠问题。

希望这有助于其他人尝试实现同样的目标!此致!

相关问题