goldfire / howler.js

Javascript audio library for the modern web.
https://howlerjs.com
MIT License
24.03k stars 2.24k forks source link

Max stack reached when setting volume every frame and context not running yet #1662

Open signorpipo opened 1 year ago

signorpipo commented 1 year ago

The Problem

If I set the volume every frame on a SPECIFIC audio, and also apply a fade, the audio is not loaded and the context is not running (yeah sort of specific and can't 100% replicate even though happens often), howler throws a max stack reached because it keeps emitting the volume events and the queue is filled with them (since I kept updating the volume and fading while the audio was loading).

It is not blocking or anything, it seems like it just displays the error but then it works fine.

2599

Reproducible Example

No response

Reproduction Steps

  1. Create a new audio
  2. Set the volume every frame on that audio
  3. Possible also apply a fade at some point
  4. Click on the page to trigger the context
  5. 1/10 it triggers the error

Possible Solution

I guess the issue here is that, since the context is not running the set volume request is getting added indefinitely to the queue and it gets so big that the loadQueue function, which shift one and then recursively call itself, create a super long stack.

loadQueue: function(event) {
    var self = this;
    if (self._queue.length > 0) {
      var task = self._queue[0];
      if (task.event === event) {
        self._queue.shift();
        self._loadQueue(); //<- here
      }
      if (!event) {
        task.action();
      }
    }
    return self;
  }

Maybe this should just be a for loop instead of a recursive call?

  loadQueue(event) {
      let self = this;
      if (self._queue.length > 0) {
          while (self._queue[0].event === event) {
              let task = self._queue[0];
              self._queue.shift();

              if (!event) {
                  task.action();
              }
          }
      }
      return self;
  }

Something like this, which is not completely correct, in fact I don't know why u recursively call loadQueue but without an event, calling action only on the next task and not the one with the event. I don't know the whole library so this might makes sense.

Context

No response

Howler.js Version

2.2.3+mediastream-support-4

Affected Browser(s)/Versiuon(s)

No response

barisyild commented 2 months ago

The problem occurs mostly in mobile browsers.

barisyild commented 2 months ago

https://github.com/goldfire/howler.js/issues/1462