howler.js
howler.js copied to clipboard
HTML5 Audio pool exhausted
So I have a website where you can hover on div and this starts to play a song. There are maaany of these divs there and I had a lot of bugs along the way, but I finally got to the point where the site is not that buggy. Actually, there is just one bug now. When I play a few songs by hovering over different divs and then I reload the page, it sometimes happens that the sound is not played until I clear cache or hard-refresh the page. The browser says:
HTML5 Audio pool exhausted, returning potentially locked audio object.
Here is my code:
$(this).hover(
function() {
$("#spinner-loading-voice").css("display", "block");
if (sound != null) {
if (sound.playing()) {
sound.stop();
sound.unload();
}
}
sound = new Howl({
src: voice["mp3_local_path"],
format: "mp3",
html5: true,
onload: function() {
if (sound != null) {
if (!sound.playing()) {
sound.play();
} else {
sound.stop();
sound.unload();
sound.play();
}
}
$("#spinner-loading-voice").css("display", "none");
},
onplayerror: function() {
sound.once('unlock', function() {
sound.play();
});
}
});
},
function() {
sound.unload();
$("#spinner-loading-voice").css("display", "none");
}
);
For now, let's ignore how messy the code is. My question is - can I somehow clear the Audio pool?
After a short research, it seems to me that either Howler isnt draining the audio pool properly, or I have to specifically tell it to release everything from the pool. Is anything like this possible?
smae issue here with safari 12.0.2 (never had this issue in chrome though.. )
I had the same issue with Safari. Anyone knows what's the solution is? Thanks :)
I need to fix this urgently... but I can't find a solution :(
I've been running into this with Chrome as well
Can’t we manually clean the audio pool? But how does one do that?
+1 also receiving this warning in safari
+1 It looks like this might be an issue we mainly have on iPads.
+1 this is an issue for me in the safari browser both on laptop and phone.
I'm using the react-howler wraper thought, it works fine the first time the site is loaded but if I reload I get the same warning also it seams like duration is returning Infinity
.
The audio plays just fine thought (even after realod), but i can't seek a new position (can't skip forward or backward) perhaps related to the issue with calculating the audio length.
Edit: I tried disabling the service worker (stoping it from registering) when the browser used is safari and that seams to have solved the issue I was having, I'm thinking that the main issue in my case was that safari was locking the audio after it beeing cached or something like that (altought it did not seam to mather if I was playing a previusly fetched audio or not :S)
+1 on chrome
+1 in chrome
+1 on chrome
+1 iOs Safari
any work around?
FYI...I had the problem with large files with a backend that didn't support partial-downloads (HTTP 206). Once I implemented "Content-Range" support the error went away.
spoke too soon...the error wasn't gone. I am now using
The workaround I'm using now come from here.
Basically I generate an array of activated
howlers on first interaction (click). Then, when I need to play a sound, I use the longest not-used howler in my array and use the custom changeSrc Method.
When using the standard audio pool from howler, it discards each used howler, so the pool is exhausted after some time. In my case I had just one interaction to play many sounds, so I couldn't rely on the finite audiopool.
A thing I missed in the beginning: Initiate an empty howler on first interaction, otherwise the pool doesn't get filled with active audios. I had it in a delay and was wondering, why the pool doesn't work at all.
In general, it would be nice to have an option to recycle used howlers from the pool. @goldfire is there a way this could be implemented or is there a reason, old howlers from the pool get discarded?
+1 for Firefox
+1 safari ios
+1 for firefox Ubuntu
@SebastianGerS > +1 this is an issue for me in the safari browser both on laptop and phone.
I'm using the react-howler wraper thought, it works fine the first time the site is loaded but if I reload I get the same warning also it seams like duration is returning
Infinity
.The audio plays just fine thought (even after realod), but i can't seek a new position (can't skip forward or backward) perhaps related to the issue with calculating the audio length.
Edit: I tried disabling the service worker (stoping it from registering) when the browser used is safari and that seams to have solved the issue I was having, I'm thinking that the main issue in my case was that safari was locking the audio after it beeing cached or something like that (altought it did not seam to mather if I was playing a previusly fetched audio or not :S)
Did this permanently solve your problem?
@usergit yea as far as I could tell. It was just a school project and the site it's not up at the moment, but I can't recall having any problems after I disabled the service-worker for safari while the server was up.
I was facing the same problem after reviewing my code I noticed that I was getting the error due to empty Howler src. I'm using Vue Js so the URL src comes from the store and it gets from external API. When the upload for the first milliseconds the src is empty.
My Solution: Make sure that the howler src is not empty
+1 for chrome 79 MacOS, Windows, Linux. Not permanently.
Big Files are giving this error some times. Tried on Chrome, Safari Mac, Safari iOS. Chrome is warning but is playing, whereas Safari sometimes play or some times gives onplayerror
.
After digging into code it seems to be thrown when it can't playtest audio. https://github.com/goldfire/howler.js/blob/master/src/howler.core.js#L408
var testPlay = new Audio().play();
if (testPlay && typeof Promise !== 'undefined' && (testPlay instanceof Promise || typeof testPlay.then === 'function')) {
testPlay.catch(function() {
console.warn('HTML5 Audio pool exhausted, returning potentially locked audio object.');
});
}
And I guess the problem is that large files loads in AudioPool
and then there is no space for blank audio to play.
This doesn't seem to be affected by file size on my end. I'm able to work around the issue where I still get the warning on first load in Mac Safar 13.1.2, but the sounds never stop playing. The also play in iOS Safari.
- I am doing @vin-ni's suggestion of an empty Howl right away
- I think the critical thing is to manually call unload() on the sound when I stop it, which seems to recycle it from the pool (since Howler's automatic recycling seems to be failing)
One problem is that if there is no user activity and you try to play sound then also "Audio Pool Exhausted" will come as an error. Check for that too. This worked for me.
I get "Audio Pool Exhausted" when I refresh a page and try to play long audio (big file)
does anyone know the solution to the problem I described above?
I was able to get rid of it by, according to my own comment to myself: //create an empty howler right away to try to fix html5 audio pool exhaustion bug as specified here: https://github.com/goldfire/howler.js/issues/1110#issuecomment-498197664
Then before playing a new one, stop the previous sound and then unload it each time.
Howler.stop(); Howler.unload();
https://worries.io/bash/
On Mon, Oct 26, 2020 at 7:49 AM rchaban [email protected] wrote:
does anyone know the solution to the problem I described above?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/goldfire/howler.js/issues/1110#issuecomment-716496966, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABFDFPLKLJ46FVESACONWTSMVO47ANCNFSM4GMSRZGQ .
I get this when using the latest version of Safari (v. 14.0.1) on MacOS, using the latest release of Howler.
We have a web app that lets users record and playback. Recording and playing back work perfectly in Chrome.
However, in Safari, until very recently, recording didn't work (we're using standard web audio recording), though now it KIND of works (audio quality is poor).
Also in Safari, I'm getting this "HTML Audio pool exhausted" message from Howler, and playback doesn't happen - instead I get onLoadError called, with: id=1001, error=4 (MEDIA_ERR_SRC_NOT_SUPPORTED).
I'm not doing anything especially complex with Howler, just simple playback. I've configured it to play back webm, opus and wav. Our environment records raw 16-bit WAV, and puts an AU header on it (since it's a very simple header and allows for streaming without needing to modify the header with metadata from the rest of the file). However, when streaming to a browser playing back with web audio (as opposed to Flash, which we used to use), we replace that header with a basic WAV header, so that the browser understands it.
As mentioned, this works perfectly in Chrome, but not in Safari.
Is WAV playback in Howler known to not work in Safari? I tried the above idea of creating an empty Howler, then stopping and unloading it, before creating the one I want to use. I also tried adding the "Content-Range" HTTP header. Neither has helped at all, and I still get the same error.
The files we're streaming CAN be pretty large, but for my test purposes, they're only a few seconds long.
This is happening with the simplest of scenarios. First playback, first Howler instance created, no prior playbacks, etc.
Anyone have any suggestions? Not sure why I'm getting this audio pool error, but does the above failing with "MEDIA_ERR_SRC_NOT_SUPPORTED" mean that Safari just doesn't like 16-bit PCM with a generic WAV header?
UPDATE: I found that the "HTML5 Audio pool exhausted" messages only appears on the first playback attempt. Subsequent attempts don't show that message. However, I'm still getting the inability to play back clips of the abovementioned type. I'll create another issue specifially regarding the audio error (not the pool error, since that seems like it might be a red herring here).
- Tim
For me I solved this bug with adding event on the new howl objet
In typeScript
sound: Howl; // my sound object
Howler.autoUnlock = true;
Howler.html5PoolSize=100; // It's because I play a lot of sounds
playSoundHowl(){
this.sound = new Howl({
src: 'src/...',
html5: true,
loop: false,
preload: true,
});
this.sound.once('load', () => {
this.idSoundPlaying = this.sound.play();
})
this.sound.once('loaderror', () => {
Howler.unload();
});
this.sound.once('playerror', () => {
Howler.unload();
});
this.sound.once('stop', () => {
});
this.sound.once('unlock', () => {
});
this.sound.once("end", () => {
this.sound.stop(this.idSoundPlaying);
})
https://github.com/leithdm/milestone-project-2/issues/98
I got the same warnings after refresh page. I have event listener song.once('unlock', callback) and when I make click anywhere I trigger event unlock and there (in callback function I can invoke play() again). And this 'click' should be from user. when you try to do 'document.body.click()' nothing happen. Who knows some solution?
This issue still occurs but its very specific to IONIC on IOS. Any help guys please.
Is that fixed?
This issue still occurs but its very specific to IONIC on IOS. Any help guys please.
@kayuse I had the same Ionic (Angular) issue under iOS, i'm not sure is it the best solution, but it works for me.
import { Component, OnDestroy, OnInit } from "@angular/core";
import { Platform } from "ionic-angular";
import { Subject, fromEvent } from "rxjs";
import { filter, takeUntil } from "rxjs/operators";
declare const window;
@Component({
selector: 'audio-component',
templateUrl: 'audio.component.html'
})
export class AudioComponent implements OnInit, OnDestroy {
howl:Howl;
playingHowlID:number;
AudioContext:AudioContext;
destroy$ = new Subject();
isIOS = this.platform.is("ios");
constructor(private platform: Platform) {}
ngOnInit(){
this.initHowl();
if(this.isIOS) {
const ctx = window.AudioContext || window.webkitAudioContext;
if(ctx){
this.AudioContext = new ctx();
fromEvent(this.AudioContext, "statechange")
.pipe(
filter((res) => (this.AudioContext.state as string) === "interrupted"),
takeUntil(this.destroy$)
)
.subscribe(() => {
this.handleAudioInterrupting();
})
}
}
}
initHowl(){
this.howl = new Howl({
src: 'your sound path',
html5: true
})
}
toggleAudioState(pause:boolean){
pause ? this.howl.pause() : this.playingHowlID = this.howl.play();
}
handleAudioInterrupting(){
this.playingHowlID ? this.howl.pause(this.playingHowlID) : null;
this.howl.play();
}
ngOnDestroy(){
this.destroy$.next();
this.destroy$.complete();
if(this.AudioContext) this.AudioContext.close();
}
}
it seems it has nothing to do with the amount or size of audio files, you'll receive this warning even if you are just trying to silently preload an audio file using html5 without playing it on page load, which is kinda weird
Does anyone have a simple test case for this? From reading through the thread, I'm not actually seeing any bug in howler described. The warning is thrown when an HTML5 sound is loaded before audio has been unlocked. Each HTML5 audio noe must be unlocked individually on user input, which howler handles automatically. You'll get that warning on load (which I suppose could be suppressed if that is the issue being described), but the sound should still play normally if it is first played through user input. That isn't a limitation of howler but how all of the browser now function.
- Put your cursor on the webpage when the music are calling to play!
- Because we put the cursor out of the website page, somewhere like Chrome Devtools,
- so broswer think this is risk, so it won't play the music!
- This is not the error with Hower. All Audio base plugin will ban this behavior.