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

HTML5 Audio Slow / Stuttering on iOS #35937

Closed
davidCentervention opened this issue Feb 5, 2020 · 24 comments · Fixed by #38816
Closed

HTML5 Audio Slow / Stuttering on iOS #35937

davidCentervention opened this issue Feb 5, 2020 · 24 comments · Fixed by #38816

Comments

@davidCentervention
Copy link

davidCentervention commented Feb 5, 2020

Godot version: 3.2 (also seeing the same issue with Godot 3.1, and 3.1.1)

OS/device including version: iPad 5th generation running iOS 13.3.1

Issue description: I'm seeing audio playing REALLY slow and stuttering (sounding robotic) on iPad HTML5 builds using .wav and ogg files.

Steps to reproduce: Create a blank project,, add an AudioStreamPlayer and load a .ogg or .wav file in the AudioStreamPlayer and set it to play that audio file on a loop. Export to HTML5 and play on an ipad and the audio will play very glitchy, it will sound slow and robotic.

Minimal reproduction project: https://drive.google.com/file/d/14XzsamzGlBn_vx2y2OXpdhtkwTxjWEco/view?usp=sharing

@Calinou
Copy link
Member

Calinou commented Feb 5, 2020

@davidCentervention Please upload a minimal reproduction project to make this easier to troubleshoot.

@davidCentervention
Copy link
Author

@davidCentervention davidCentervention changed the title HTML5 Audio Slow on iOS HTML5 Audio Slow / Stuttering on iOS Feb 6, 2020
@ChronoDK
Copy link

I have this problem as well, but on an iPhone 11 with iOS 13.3.1.
Happens with all sounds, looped or not.

@Julian-Vos
Copy link

Julian-Vos commented Mar 18, 2020

Same problem here, on an iPad Air 2 with iOS 12.4, Godot 3.1.2.

I spent a few hours trying to work around it, but to no avail. It seemed suspicious that the default sampleRate of the audioContext was 48000 on my laptop and Android phone, which play my HTML5 sounds just fine, yet 44100 on the iPad. However, all my sounds are actually mixed with a sample rate of 44100, and my laptop still plays them right when setting the audioContext's sampleRate to 44100. I cannot set the audioContext's sample rate on the iPad, but resampling the sounds to 48000 didn't change anything. Also, the sounds are played back about twice as slow, instead of the 48000 / 44100 = 1.09x you would expect. Doubling their pitch_scale in Godot made the durations approximately right, but they still sounded robotic.

However, the iPad could play the same sounds just fine when using the Web Audio API directly. Hence I assume the problem can be solved in either Godot or WebAssembly/Emscripten, unless it's a performance/thread problem.

@caizu
Copy link

caizu commented Mar 26, 2020

Same here. For me it looks like a buffering as the sounds distort in the beginning / after loading very much but suddenly it might clear up if you play the game further. Another interesting thing is that sounds get better if you minimize the browser. And the sounds continue playing if you close the browser.

Godot version 3.2 Custom (with asm.js support)
iPad mini 2, iOS 12.4 (as well as all other iPads and iPhones we have tried)

@Tinkersedge
Copy link

Having the same exact issues. So weird that when you minimize the browser, it plays the sound clear for a couple of seconds. Must be a loading issue of some sort.

Godot version 3.2 - GLES2 build
iphone 11, iOS13,

@Tinkersedge
Copy link

Has anyone found a way to make this work yet? A work around?

@Calinou
Copy link
Member

Calinou commented Apr 18, 2020

@Tinkersedge Not that I know of. See also #26554.

@davidCentervention
Copy link
Author

davidCentervention commented Apr 18, 2020

@Tinkersedge For me the work-around was to handle audio entirely outside of Godot for HTML5 for the time being. I call Javascript from Godot to load mp3s from the web into an audio tag on my HTML page and play audio from there, completely bypassing the audio engine in Godot to use the audio played by the browser.

My assumption is the issue in Godot is likely due to the auto-play audio changes that went in most browsers in the last few years that require audio to be initiated by an interaction (click) by the end user: https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/

@Tinkersedge
Copy link

@davidCentervention any chance you could share a super simple version of how you did that? Is that method able to handle background audio as well as sound effects? Thank you so much for telling me about the work around. Hopefully I can still make this game happen on tablets.

@ChronoDK
Copy link

I tried a lot of things, for instance different sample rates and creating a new audio context. Nothing worked for me. I guess the work-around by @davidCentervention is the only way for now.

@caizu
Copy link

caizu commented Apr 20, 2020

@Tinkersedge @davidCentervention @ChronoDK We finally actually managed to solve this: my colleague modified JS audio driver source code and recompiled the Engine's export template. I'll ask him to drop the solution here as well.

@ChronoDK
Copy link

@caizu Amazing, I hope the fix can be added to a release soon then.

@caizu
Copy link

caizu commented Apr 21, 2020

@ChronoDK I hope it too and I asked my colleague to do that.

@teknobilly
Copy link

teknobilly commented May 5, 2020

I'm experiencing this problem with IPads and IPhones in a simple html5 game made with Godot Engine 3.2

my colleague modified JS audio driver source code and recompiled the Engine's export template

I was hoping issue #38215 for v4 might help this case. I managed to hack the AudioServer::Init function and compiled the WebAssembly file with version 3.2.2 source. But am still experiencing the issue.
This is my first foray into debugging source code and I am feeling really happy having achieved this much. But I am still having this issue with Audio on IOS devices new and old, ipad and iphone, with updated IOS.

@thomazette
Copy link

thomazette commented May 7, 2020

Hello people, the great problem is the buffer_size!
Godot audio driver use createScriptProcessor with the first value zero!

So the device, set by default the buffer_size! I dont know why IOS system is so shit, to set 256 on the buffer_size!

image

I put this trative, when the buffer_size is lower 2048 they set 2048.

Below is the template export with that trative, just extract into folder \AppData\Roaming\Godot\templates\3.2.1.stable

3.2.1.stable.zip

I hope helped sameone!!

@dpensky
Copy link

dpensky commented May 8, 2020

Hello people, the great problem is the buffer_size!
Godot audio driver use createScriptProcessor with the first value zero!

So the device, set by default the buffer_size! I dont know why IOS system is so shit, to set 256 on the buffer_size!

image

I put this trative, when the buffer_size is lower 2048 they set 2048.

Below is the template export with that trative, just extract into folder \AppData\Roaming\Godot\templates\3.2.1.stable

3.2.1.stable.zip

I hope helped sameone!!

This fixed my issue. Thanks.
I hope they put this on the officials templates

@Calinou
Copy link
Member

Calinou commented May 8, 2020

I hope they put this on the officials templates

Feel free to open a pull request for this 🙂

@Tinkersedge
Copy link

Hello people, the great problem is the buffer_size!
Godot audio driver use createScriptProcessor with the first value zero!

So the device, set by default the buffer_size! I dont know why IOS system is so shit, to set 256 on the buffer_size!

image

I put this trative, when the buffer_size is lower 2048 they set 2048.

Below is the template export with that trative, just extract into folder \AppData\Roaming\Godot\templates\3.2.1.stable

3.2.1.stable.zip

I hope helped sameone!!

For me, it fixed the ipad issue, but my iphone is back to not loading like it was before the last update. I will try again in case I did something wrong.

@thomazette
Copy link

Hello people, the great problem is the buffer_size!
Godot audio driver use createScriptProcessor with the first value zero!
So the device, set by default the buffer_size! I dont know why IOS system is so shit, to set 256 on the buffer_size!
image
I put this trative, when the buffer_size is lower 2048 they set 2048.
Below is the template export with that trative, just extract into folder \AppData\Roaming\Godot\templates\3.2.1.stable
3.2.1.stable.zip
I hope helped sameone!!

For me, it fixed the ipad issue, but my iphone is back to not loading like it was before the last update. I will try again in case I did something wrong.

Maybe is the buffer lower, the Godot Team put 4096, i set 2048! If dont work to you, i upload with that value to 4096!

@Arbint
Copy link

Arbint commented Jun 18, 2020

I have tried the template with no luck, so I pushed my butt to learn Java and html 5, and found a solution to play my video through Java:

image
image

So basically you use the JavaScript.eval to evaluate your java script to directly add a video player html 5 element to the body of your webpage. That Java identifier is a preload script.

@ChronoDK
Copy link

I have found audio to be working just fine on iOS with the latest beta and release candidates, so that javascript workaround should not be needed anymore.

@IvanF
Copy link

IvanF commented Jun 23, 2020

The issue was connected with size of buffering in platform/javascript/audio_driver_javascript.cpp
there was the part of code:

buffer_length = EM_ASM_INT({
                var CHANNEL_COUNT = $0;
                var channelCount = _audioDriver_audioContext.destination.channelCount;
                try {
                        // Try letting the browser recommend a buffer length.
                        _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(0, 2, 1);
                } catch (e) {
                        // ...otherwise, default to 4096.
                        _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(4096, 2, 1);
                }
                _audioDriver_scriptNode.connect(_audioDriver_audioContext.destination);

                return _audioDriver_scriptNode.bufferSize;
        }, channel_count);

and in next string by "// Try letting the browser recommend a buffer length." need to be replaced zero to i.g. 16384. That's it. Safari can not determine the size and it falls to 0 causing crackles.

@akien-mga
Copy link
Member

@IvanF Indeed, that was fixed in 245c179 and #39037. The fix is available in Godot 3.2.2.

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

Successfully merging a pull request may close this issue.