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

Recent Chrome changes to sound autoplay settings #6511

Closed
kripken opened this issue May 7, 2018 · 24 comments
Closed

Recent Chrome changes to sound autoplay settings #6511

kripken opened this issue May 7, 2018 · 24 comments

Comments

@kripken
Copy link
Member

@kripken kripken commented May 7, 2018

Chrome now blocks audio from automatically playing. We are seeing reports of games and art being broken or audioless because of this.

To mitigate it, perhaps we should

@kripken
Copy link
Member Author

@kripken kripken commented May 8, 2018

A good summary of the problems people are encountering: https://twitter.com/mcclure111/status/993627449991688193

@Kaosumaru
Copy link

@Kaosumaru Kaosumaru commented May 8, 2018

I guess, generic polyfill for AudioContext on chrome could be added, making them 'auto-resumable' when user interacts with website. Not sure why chrome devs don't choose this to be default behavior, would be more backward compatible.

@kripken
Copy link
Member Author

@kripken kripken commented May 8, 2018

@Kaosumaru yeah, we might want that. Not sure yet though what the best polyfill is. Here is one option:

https://gist.github.com/surma/301c9c377aaf90a3fdae615d4840bb2e

@ruby0x1
Copy link

@ruby0x1 ruby0x1 commented May 12, 2018

It's worth noting that this change is unacceptable on chrome's behalf, so while a polyfill is helpful, everyone who cares about the web platform should be making their voice heard to chrome as well.

Akaricchi added a commit to taisei-project/taisei that referenced this issue Mar 6, 2019
Akaricchi added a commit to taisei-project/taisei that referenced this issue Mar 6, 2019
Akaricchi added a commit to taisei-project/taisei that referenced this issue Mar 9, 2019
* Major refactoring of the main loop(s) and control flow (WIP)

run_at_fps() is gone 🦀

Instead of nested blocking event loops, there is now an eventloop API
that manages an explicit stack of scenes. This makes Taisei a lot more
portable to async environments where spinning a loop forever without
yielding control simply is not an option, and that is the entire point
of this change.

A prime example of such an environment is the Web (via emscripten).
Taisei was able to run there through a terrible hack: inserting
emscripten_sleep calls into the loop, which would yield to the browser.
This has several major drawbacks: first of all, every function that
could possibly call emscripten_sleep must be compiled into a special
kind of bytecode, which then has to be interpreted at runtime, *much*
slower than JITed WebAssembly. And that includes *everything* down the
call stack, too! For more information, see
https://emscripten.org/docs/porting/emterpreter.html

Even though that method worked well enough for experimenting, despite
suboptimal performance, there is another obvious drawback:
emscripten_sleep is implemented via setTimeout(), which can be very
imprecise and is generally not reliable for fluid animation. Browsers
actually have an API specifically for that use case:
window.requestAnimationFrame(), but Taisei's original blocking control
flow style is simply not compatible with it. Emscripten exposes this API
with its emscripten_set_main_loop(), which the eventloop backend now
uses on that platform.

Unfortunately, C is still C, with no fancy closures or coroutines.
With blocking calls into menu/scene loops gone, the control flow is
reimplemented via so-called (pun intended) "call chains". That is
basically an euphemism for callback hell. With manual memory management
and zero type-safety. Not that the menu system wasn't shitty enough
already. I'll just keep telling myself that this is all temporary and
will be replaced with scripts in v1.4.

* improve build system for emscripten + various fixes

* squish menu bugs

* improve emscripten event loop; disable EMULATE_FUNCTION_POINTER_CASTS

Note that stock freetype does not work without
EMULATE_FUNCTION_POINTER_CASTS; use a patched version from the
"emscripten" branch here:

    https://github.com/taisei-project/freetype2/tree/emscripten

* Enable -Wcast-function-type

Calling functions through incompatible pointers is nasal demons and
doesn't work in WASM.

* webgl: workaround a crash on some browsers

* emscripten improvements:

    * Persist state (config, progress, replays, ...) in local IndexDB
    * Simpler HTML shell (temporary)
    * Enable more optimizations

* fix build if validate_glsl=false

* emscripten: improve asset packaging, with local cache

Note that even though there are rules to build audio bundles, audio
does *not* work yet. It looks like SDL2_mixer can not work without
threads, which is a problem. Yet another reason to write an OpenAL
backend - emscripten supports that natively.

* emscripten: customize the html shell

* emscripten: force "show log" checkbox unchecked initially

* emscripten: remove quit shortcut from main menu (since there's no quit)

* emscripten: log area fixes

* emscripten/webgl: workaround for fullscreen viewport issue

* emscripten: implement frameskip

* emscripter: improve framerate limiter

* align List to at least 8 bytes (shut up warnings)

* fix non-emscripten builds

* improve fullscreen handling, mainly for emscripten

* Workaround to make audio work in chromium

emscripten-core/emscripten#6511

* emscripten: better vsync handling; enable vsync & disable fxaa by default
@Beuc
Copy link
Contributor

@Beuc Beuc commented Apr 11, 2019

Any news on getting the audio to work with Chrome's autoplay policy? :)

@Beuc
Copy link
Contributor

@Beuc Beuc commented Apr 14, 2019

For the record my current all-JavaScript work-around:

      // Work-around chromium autoplay policy
      // https://github.com/emscripten-core/emscripten/issues/6511
      function resumeAudio(e) {
	  if (typeof Module === 'undefined'
	      || typeof Module.SDL2 == 'undefined'
	      || typeof Module.SDL2.audioContext == 'undefined')
	      return;
	  if (Module.SDL2.audioContext.state == 'suspended') {
	      Module.SDL2.audioContext.resume();
	  }
	  if (Module.SDL2.audioContext.state == 'running') {
	      document.getElementById('canvas').removeEventListener('click', resumeAudio);
	      document.removeEventListener('keydown', resumeAudio);
	  }
      }
      document.getElementById('canvas').addEventListener('click', resumeAudio);
      document.addEventListener('keydown', resumeAudio);

@kripken
Copy link
Member Author

@kripken kripken commented Apr 18, 2019

@Beuc Is there a good place in our default HTML to add that?

@Beuc
Copy link
Contributor

@Beuc Beuc commented Apr 18, 2019

I put it right after the <canvas> tag in shell.html.
However this is somewhat specific to SDL2.

@kripken
Copy link
Member Author

@kripken kripken commented Apr 22, 2019

I wonder if we shouldn't add it in the SDL2 port, then. Worth opening a PR or at least an issue to discuss that there.

It would also be good to add more details on this to our docs, like say in the FAQ.

@Beuc
Copy link
Contributor

@Beuc Beuc commented Apr 23, 2019

Haha, there already is (cf. emscripten-ports/SDL2#57 in this item's description) - where you pointed people here for a more library-independent solution ;)

@kripken
Copy link
Member Author

@kripken kripken commented Apr 25, 2019

Heh, yeah, I guess this just isn't generic code, and should be in SDL2. I'll comment there, thanks.

@raysan5
Copy link

@raysan5 raysan5 commented May 22, 2019

I worked on this issue today for raylib and just implemented a RESUME/SUSPEND button in my shell.html. It's based on the Google proposed solution.

Here it is a working example implementing this shell.

@ghost
Copy link

@ghost ghost commented Mar 15, 2020

A little late, but I thought I'd chime in anyways. @raysan5 has a good way of enumerating audio contexts that is not specific to SDL2. It may be wise to add something like that to the default shell. I personally prefer to build libraries from source rather than using Emscripten ports.

@kripken
Copy link
Member Author

@kripken kripken commented Mar 16, 2020

@fluffrabbit I agree that could be useful. PR would be welcome. One thing to consider though is that it would be good to not emit this if it isn't necessary (to not increase code size of code not using audio), which I'm not sure how to do offhand. If there isn't a good way, it might be added as an option.

@ghost
Copy link

@ghost ghost commented Mar 16, 2020

@kripken So, shell_minimal_audio.html? Not sure about the internals of Emscripten's build system; my use case mainly requires working code in my own dark theme. I'll work on it as soon as I can.

@Beuc
Copy link
Contributor

@Beuc Beuc commented Mar 17, 2020

Nice. This looks like a small snippet of javascript so I would just add it to shell.html (not "minimal", nor another "audio" variant).

@ghost
Copy link

@ghost ghost commented Mar 17, 2020

@Beuc The other guy has commit access, so I'll wait for more feedback. However, keeping the code shorter and not duplicating too much sounds good to me. Also, this particular workaround relies on the user either clicking on the canvas or pressing a key. Is this acceptable?

@kripken
Copy link
Member Author

@kripken kripken commented Mar 17, 2020

I just commented in the PR - maybe best to move the discussion there? (That's an interesting point, @Beuc , that maybe we should consider adding this to the regular shell but not minimal. However I sort of prefer the PR's current code of a new file as I wrote there.)

@fluffrabbit I think it's unavoidable to require the user clicking on something, as I understand it that's the only way for browsers to allow audio now. So I think it's the right approach.

@raysan5
Copy link

@raysan5 raysan5 commented Mar 17, 2020

@kripken Just a side note on a related issue, for some reason my shell stopped displaying the icons properly (audio on/off) after updating to upstream version 1.39.9, it worked previously with 1.38.42-upstream (sorry for the versions gap). I saw that generated .html (minimized) has the icons mangled (converted to equivalent ASCII chars).

In the meantime I changed shell.html to avoid using the icons... but it's more ugly.

EDIT: I think it could be related in the way shell.html is read for processing... maybe related to Python version change? It worked with python 2.7.13 and now it uses python 3.7.4.

@kripken
Copy link
Member Author

@kripken kripken commented Mar 17, 2020

@raysan5 I'm not sure what you mean exactly, but I believe @juj started to minify the HTML in that range of commits, so that sounds like the cause maybe - perhaps something is being minified that should not be?

Perhaps you can provide a testcase to verify, that would help.

@raysan5
Copy link

@raysan5 raysan5 commented Mar 18, 2020

@kripken here some images to better illustrate the issue:

example compiled with 1.38.42-upstream:

shell_icons_ok

example compiled with 1.39.9:

shell_icons_wrong

With latest version, icons (4 bytes utf8) are converted to the equivalent ASCII (4 bytes).

EDIT 1: Attaching my shell.html with icons: shell.zip

EDIT 2: I think issue is not about minification process but how the shell.html string is read for processing, it should be read and processed as UTF-8. I guess it's probably converted to ASCII when read.

@kripken
Copy link
Member Author

@kripken kripken commented Mar 18, 2020

@raysan5 yeah, I'd guess that is related to the new processing of html files.

To make sure this isn't missed I'd suggest opening a new issue for it.

@raysan5
Copy link

@raysan5 raysan5 commented Mar 30, 2020

@kripken Excuse me for the delay, just opened a new issue for this: #10802.

@stale
Copy link

@stale stale bot commented Jun 4, 2021

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.

@stale stale bot added the wontfix label Jun 4, 2021
@stale stale bot closed this Jul 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

5 participants