Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoundManager is always suspended when AudioContext not available, preventing sound playback #4757

Closed
roger-o3h opened this issue Oct 17, 2022 · 6 comments · Fixed by #4789
Closed
Labels

Comments

@roger-o3h
Copy link

roger-o3h commented Oct 17, 2022

Description

When you are running in an environment without html5 web audio — hasAudioContext() is false (https://github.com/playcanvas/engine/blob/main/src/platform/audio/capabilities.js#L8) — the SoundManager always reports that it is suspended (https://github.com/playcanvas/engine/blob/main/src/platform/sound/manager.js#L117) because its _context is always null. A downstream problem this creates is that audio clips will never play.

Furthermore, _unlocked never has an opportunity to be set to true without AudioContext being present, as the only place it's set is the lazy creation of the AudioContext (https://github.com/playcanvas/engine/blob/main/src/platform/sound/manager.js#L139-L142) and this too causes SoundManager to perpetually report it is in a suspended state, preventing sound playback.

One potential fix would be to provide different implementations of suspended getter:

    get suspended() {
        if (hasAudioContext()) {
            return !this._context || !this._unlocked || this._context.state !== CONTEXT_STATE_RUNNING;            
        } else {
            return this._selfSuspended;
        }
    }

I think this is somewhat critical as it seems to break all sound playback in our project. We have a polyfill for HTMLAudioElement in order to route audio through our native app hosting the web view. We force PC to use legacy sound mode by

    delete window.AudioContext;
    delete window.webkitAudioContext;

before loading in PC. (It would be cool to have an option to do this, like the OPPOSITE of forceWebAudioApi). Our situation is a bit weird, but this issue should equally affect folks who truly don't support html5 web audio.

I'm building a minimal test case and will edit and attach it when complete.

@roger-o3h
Copy link
Author

pc-issue-4757.zip
Attached is a simple repro case. Press the button, get a sound.

  • webaudio.html works normally, if you view in a browser with HTML5 web audio
  • legacy.html you will notice no sound, emulating a browser without HTML5 web audio

@yaustar
Copy link
Contributor

yaustar commented Oct 19, 2022

@roger-o3h is this a regression issue (ie was this working in a previous release of the engine)?

@roger-o3h
Copy link
Author

roger-o3h commented Oct 19, 2022

@roger-o3h is this a regression issue (ie was this working in a previous release of the engine)?

Yes, was working at least up to 1.52.6.

I think this introduced the error #4462 around 1.56

@roger-o3h
Copy link
Author

Just to update, after applying #4788, the issue with legacy html audio is still present. In instance.play() this still runs:

            // suspend immediately if manager is suspended
            if (this._manager.suspended)
                this._onManagerSuspend();

and in the new logic, suspended is still dependent on an AudioContext:

	get running() {
        return this._context && this._context.state === CONTEXT_STATE_RUNNING;
    }

    get suspended() {
        return !this.running;
    }

With legacy html audio, there will never be a _context, running will always be false and suspended will always be true, pausing sound instances.

One way to fix this would now be to change suspended to be dependent on whether AudioContext is available:

    get suspended() {
        if (this.AudioContext) {
            return !this.running;
        } else {
            return this._userSuspended;
        }
    }

Or, something could be changed in instance.js in the play() prototype specific to if (!hasAudioContext()).

Grateful for the related fix! Only trying to be helpful in keeping this bug report up to date 🙏

@willeastcott
Copy link
Contributor

@roger-o3h Thanks for this info!! I'm sure @slimbuck will get back to you on this tomorrow. But just to confirm, presumably legacy HTML Audio is only used in IE11 these days, right?

@roger-o3h
Copy link
Author

@roger-o3h Thanks for this info!! I'm sure @slimbuck will get back to you on this tomorrow. But just to confirm, presumably legacy HTML Audio is only used in IE11 these days, right?

It's true, should be very uncommon now, but I do hope you continue to support it, as we are using a HTMLAudioElement polyfill that allows us to do some very custom things with routing our audio in our native application that uses a web view. 🙏

Just one user, but it's totally fine with me if, for instance, the "suspend" behaviour is dropped for this legacy mode... we just hope it continues to be an option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants