playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
https://playcanvas.com
MIT License
9.64k stars 1.34k forks source link

Oculus Browser - Error loading audio url: <mp3-file-name>: Unable to decode audio data #3511

Open ChiefBreakeverything opened 3 years ago

ChiefBreakeverything commented 3 years ago

Description

Steps to Reproduce

  1. Import any (?) mp3 file in a PlayCanvas project and set its preload flag to true.
  2. Alternatively, you can connect Chrome DevTools through ADB (guide) and call pc.app.assets.load(anyMP3Asset) through the console. This is preferred since you can also use anyMP3Asset.unload() to easily try again and inspect the error in detail.
  3. Launch the PlayCanvas application
  4. There is a very high likelihood of encountering the Unable to decode audio data error. If it doesn't happen, simply refresh or unload/reload. It seems to be more likely to happen than less.
  5. The resulting error is internal to PlayCanvas and therefore ceases further execution of the app.

Error lines

If I follow the debug links found attached to the error in Chrome DevTools, it seems to originate from this line in the AudioHandler function (also pictured in the screenshots)

    var AudioHandler = function () {
        function AudioHandler(manager) {
            this.manager = manager;
            this.maxRetries = 0;
        }

        var _proto = AudioHandler.prototype;

        _proto._isSupported = function _isSupported(url) {
            var ext = path.getExtension(url);

            if (toMIME[ext]) {
                return true;
            }

            return false;
        };

        _proto.load = function load(url, callback) {
            if (typeof url === 'string') {
                url = {
                    load: url,
                    original: url
                };
            }

            var success = function success(resource) {
                callback(null, new Sound(resource));
            };

            var error = function error(err) {
                var msg = 'Error loading audio url: ' + url.original;

                if (err) {
                    msg += ': ' + (err.message || err);
                }

                console.warn(msg);
                callback(msg); // < ----- This guy right here!
            };

            if (this._createSound) {
                if (!this._isSupported(url.original)) {
                    error("Audio format for " + url.original + " not supported");
                    return;
                }

                this._createSound(url.load, success, error);
            } else {
                error(null);
            }
        };

image image

yaustar commented 3 years ago

I'm unable to reproduce in this test project: https://playcanvas.com/project/833523/overview/oculus-vr-mp3-bug

Can you provide a test project that shows this issue please?

ChiefBreakeverything commented 3 years ago

Hm, this project doesn't seem to cause the error for me either.

I'll create an example project with the error and link it here shortly.

yaustar commented 3 years ago

If the MP3 is licensed, make it private and give 'yaustar' read access please.

ChiefBreakeverything commented 3 years ago

Done! It should be called 'Audio Debug'.

I added a small setup for quickly loading and unloading some assets.

It's definitely happening on my end (eventually) with this set of mp3s. It's much more frequent in our main project, I suppose because there are even more files = chances for it to happen?

Let me know if it's still not reproducible somehow.

yaustar commented 3 years ago

I've only managed to reproduce it once on the test project out of refreshing ~20 times. Trying again with a fork but just stuffing more files in it

yaustar commented 3 years ago

I've been trying for the last 30mins and been only able to reproduce it that one time :(

oyapiro commented 3 years ago

I think it is the same issue related to this.

Description

Steps to Reproduce

yaustar commented 3 years ago

I think it is the same issue related to this.

Description

  • It happens on Safari 15(15612.1.29.41.4, 15612) on macOS Catalina 10.15.7(19H1417). Not happens on Safari 12 and Mojave, or Safari 15 and Big Sur.
  • It happens always.
  • Dev Console says "Error loading audio url: foobar.m4a" and "Unhandled Promise Rejection: EncodingError: Decoding failed".

Steps to Reproduce

I can't reproduce this on Safari 15. The audio files in the Flappy brid project are also mp3s, not m4as

image

oyapiro commented 3 years ago

Error lines

[Error] Error loading audio url: sfx_die.mp3   (anonymous関数) (launch.js:15181)    _onFailure (playcanvas-stable.dbg.js:36752)   (anonymous関数) (playcanvas-stable.dbg.js:36689)   error (playcanvas-stable.dbg.js:33183

スクリーンショット 2021-09-24 21 45 07

)

ChiefBreakeverything commented 3 years ago

I've been trying for the last 30mins and been only able to reproduce it that one time :(

Ah, hm... I'll see if I can increase its reproducibility (so its more like what we're seeing in our main project) and I'll message you when it's easier to see.

ChiefBreakeverything commented 3 years ago

@yaustar I've recreated the conditions much better now, exact same audio files from our main project, happening 100% of the time on my end. I've added you like before. We even get the Oculus Browser Crash Corgi 😋

yaustar commented 3 years ago

Confirmed reproducible. Not sure what is causing the issue at the moment tbh. I'm wondering if there is a MP3 limit somewhere on the browser?

yaustar commented 3 years ago

@ChiefBreakeverything

Unfortunately, it's starting to look like a browser/device specific issue for the Quest and similar devices.

At a guess, because the Quest has only 4GB of RAM, it's just runs out of memory and crashes the browser. I've tried it on a similar 4G Android device with a few more MP3s and it does the same thing, crashes the browser.

You will have to work around this issue by loading and using assets that you need at a time.

yaustar commented 3 years ago

@oyapiro I've moved your issue to a new issue as it's unrelated from the looks of things. https://github.com/playcanvas/engine/issues/3525

yaustar commented 3 years ago

Tried it on an Android device with 12GB of RAM and that load the scene fine so its looking more to be a memory constraint.

ChiefBreakeverything commented 3 years ago

I suspected as much. It's strange since the Mozilla Realities browser on Quest 2 has no problem, it might just be Oculus Browser specific. An MP3 limit would be fascinating...

We already are loading and unloading as needed, unfortunately 😦 specifically fetching all assets with tags, loading when needed and unloading when needed. eachAsset.loaded returns false afterwards, etc.

yaustar commented 3 years ago

Hmm, I wonder if it be worth trying to load and unload a bunch of MP3s will cause the same issue? If it does, maybe there's s bug with unloading audio assets either in the engine or browser?

ChiefBreakeverything commented 3 years ago

Yeah that's exactly what I tested out in that first shared project. I wasn't using the exact same files so it wasn't identical, but it still happened even with as few as 8 mp3s totalling 44mb of memory. 44mb of audio with no other assets or code isn't gonna max out a Quest 2 😦 it just happens less but doesn't stop completely. I can share that project again if you want to test it out.

Edit: shared again

yaustar commented 3 years ago

44MB of memory or 44MB total file size?

ChiefBreakeverything commented 3 years ago

Ah file size, I wasn't able to check what it was taking up in memory sorry!

yaustar commented 2 years ago

@jpauloruschel had a deeper investigation into this with the following report:

  1. Loading all files crashes the device 100% of the time;
  2. Loading & immediately unloading all files crashes sometimes (probably depending on speed of download: if downloaded enough to decode and fill memory, it crashes);
  3. Loading less files never crashes, and memory profiling didn't show signs of memory leaks
  4. All Audio assets are loaded as AudioBuffer objects: https://github.com/playcanvas/engine/blob/137f6cb19fdb01caf2f936029bd76ae2fe0ce2a9/src/resources/audio.js#L137 . According to documentation (https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer), AudioBuffer objects are meant for short audio assets, and stored in-memory. Decreasing bitrate or using lower quality MP3s would definitely help mitigate the issue, but not solve it.

Final thoughts:

  • In order to properly support multiple long audio files at once, we should consider adding support for streaming-based APIs on PlayCanvas' Audio assets (probably a per-Asset setting);
  • There does not appear to be any memory leak when loading / unloading Audio files: multiple loadings + unloadings of Audio Assets do not increase heap size;
  • There is some additional memory (3 AudioContext objects) that could lead to issues, but memory footprint is small and constant.

Will keep the ticket open for reference regarding allowing support of streaming audio.