暂停然后再次播放后,HTML5音频会变得更响亮 [英] HTML5 Audio gets louder after pausing then playing again

查看:92
本文介绍了暂停然后再次播放后,HTML5音频会变得更响亮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaScript制作音频播放器,一切正常,直到我添加声音可视化器。当我暂停歌曲然后再次播放时,每次播放时声音都会变得更响,直到它被扭曲为止。

I'm making an audio player with JavaScript, everything works fine until I add a sound visualizer. When I pause the song and then play it again, the sound gets more louder every time I do it, until it gets distorsionated.

我是HTML5 Audio的新手API,我试图将音量设置为固定值,但不起作用。

I'm newbie with the HTML5 Audio API, I've tried to set the volume as a fixed value, but not works.

可视化器的代码:

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();
  }

所以,我不知道我是否做错了音频分析器,我试图创建一个全局上下文,并且每次进入该函数时都不要执行新的AudioContext(); ,我也尝试过使用以下内容指定固定量:

So, I don't know if I'm doing something wrong on the audio analyzer, I've tried to make a global context and don't do the new AudioContext(); every time I enter on the function, also I've tried to specify a fixed volume with:

audio.volume = 1; 

或使用 GainNode ,如您所见关于这个功能,但它不起作用。

or with the GainNode as you can see on the function, but it's not working.

我的错误在哪里以及为什么声音会变大?

Where is my mistake and why the sound gets louder?

问候!

---更新1 ---

--- Update 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();
      }
    };


推荐答案

好吧,因为我的草坪下车指出,我错误地添加了多个音频元素。

Well, as Get Off My Lawn pointed, I was adding by mistake multiple audio elements.

解决方案是在 playButtonFunction 之外加载歌曲的代码只做:

The solution was taking the code of load the song outside the playButtonFunction and only do:

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

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

But I still had one problem, with the next/previous functions. In these cases I need call the loadAudioElement function because the song is changing (when you press play/pause no, it's the same song) but with this I have the same problem again.

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

Well, after a bit of digging, I found that if you want to play a playlist and visualize the music all the time, YOU HAVE TO RELEASE THE OLD CONTEXT BEFORE LOAD THE NEW SONG. Not only to avoid the increase of the song volume, the cpu and memory will also get increased after 3 - 4 songs and the browser will start to run slowly depending on the machine. So:

1 - 我创建了一个名为的全局变量clearContextAudio = false;

1 - I made a global variable called clearContextAudio = false;

2 - 在我的下一个/上一个函数中,我添加了以下代码:

2 - On my next/previous functions I added this code:

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 - 在我的可视化工具(音频)功能我改变了:

3 - On my visualizer(audio) function I changed:

let context = new AudioContext();

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

它初始化为的值false因为第一次没有播放歌曲,播放完歌曲后你总是需要释放旧资源,所以变量总是设置为true。现在,你可以跳过你想要一首歌的所有时间,而不是关注内存和重叠问题。

The value it's initialized to false because the first time there is no song playing, and after play a song you will always need to release the old resources, so the variable will always set to true. Now, you can skip all the times you want a song and not concern about the memory and the overlapping issues.

希望这有助于其他人试图达到同样的目的!问候!

Hope this helps someone else trying to achieve the same thing! Regards!

这篇关于暂停然后再次播放后,HTML5音频会变得更响亮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆