goldfire / howler.js

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

Double sound init when page audio is still locked #1689

Open Tomalak opened 8 months ago

Tomalak commented 8 months ago

The Problem

Erroneous playback duplication from a single Howl using HTML5 audio when the page audio is still locked, and the Howl is set to retry playback on unlock.

Reproducible Example

No response

Reproduction Steps

On a page where audio is not allowed by default, the following runs into the expected issues with locked audio:

var howl = new Howl({
    src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Yodel_Sound_Effect.mp3',
    html5: true,
    onload(id) {
        console.log('load', this._src);
    },
    onplay(id) {
        console.log('play', id);
    },
    onend(id) {
        console.log('end', id);
    },
    onplayerror(id) {
        console.log('playerror', id);
        this.once('unlock', () => {
            console.log('unlock', id);
            this.play();
        });
    },
});

At this point, the log already shows that the AudioContext has been created/initialized twice:

An AudioContext was prevented from starting automatically. It must be created or resumed after a user gesture on the page. howler.js:2521:21
An AudioContext was prevented from starting automatically. It must be created or resumed after a user gesture on the page. howler.js:2521:21
Autoplay is only allowed when approved by the user, the site is activated by the user, or media is muted. howler.js:431:33
HTML5 Audio pool exhausted, returning potentially locked audio object. howler.js:434:18
undefined
load https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Yodel_Sound_Effect.mp3

When calling howl.play(), the playerror event occurs twice for the same ID:

Autoplay is only allowed when approved by the user, the site is activated by the user, or media is muted. [howler.js:907:28]
playerror 1002
playerror 1002
1002

Once the page receives user interaction, the unlock event occurs, and the sound starts playing duplicated, with split-second delay. The console output at that point:

unlock 1002
play 1003
load https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Yodel_Sound_Effect.mp3
play 1004
end 1003
end 1004

This does not occur on a page where the audio is allowed or has already been unlocked, or when using WebAudio.

Possible Solution

No response

Context

No response

Howler.js Version

v2.2.4

Affected Browser(s)/Versiuon(s)

Firefox 119.0

jeveloper commented 6 months ago

@Tomalak Hi Martin, I seek to commit to open source contribution in 2024 more than I have in a while. Do you still need this issue resolved?

Tomalak commented 6 months ago

@jeveloper Since there was no other option at the time, I've worked around the issue by using WebAudio instead of html5, but it does still seem like a genuine bug worth fixing.