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

No way to disable MediaSession #215

Closed
AshleyScirra opened this issue Jun 7, 2019 · 14 comments
Closed

No way to disable MediaSession #215

AshleyScirra opened this issue Jun 7, 2019 · 14 comments

Comments

@AshleyScirra
Copy link

Since Chrome started supporting MediaSession, it appears automatically even in cases it's not appropriate or unwanted, e.g. in games. I just filed a Chrome bug about this.

Shouldn't the spec have a way to disable MediaSession for when it's not wanted? There doesn't appear to be any way to do this.

@mounirlamouri
Copy link
Member

navigator.mediaSession.setActionHandler('seekbackward', null);

Should disable the action per spec. Destroying the media player would be the best way to get ride of all media session UI.

@AshleyScirra
Copy link
Author

Ah OK, missed that, thanks.

@AshleyScirra
Copy link
Author

AshleyScirra commented Jun 10, 2019

@mounirlamouri - I have tried this in Chrome for Android and it doesn't appear to work.

navigator.mediaSession.setActionHandler("seekbackward", null); appears to have no effect by itself.

If I set a null action handler for every action ("play", "pause", "seekbackward", "seekforward", "previoustrack", "nexttrack"), Chrome for Android still shows a media playback notification with a pause button, that still pauses the playback when it's pressed. Setting a no-op function instead of null is the only way I've found to disable, but not hide, the button.

Should setting a null action handler remove the button? Should setting all actions to null disable media session entirely, hiding the notification? Is this a Chrome bug?

Even if it worked, it looks brittle - as soon as a new media action handler is added, that will re-enable it again. We can't future-proof this because we'd need to know every possible action handler that will be added in future, and there already appears to be a new "stop" action on the way. Isn't this a case for a separate feature to disable it?

Destroying the media player would be the best way to get ride of all media session UI.

I don't know what you mean by this, and can't see any way to do it in the spec. Can you explain this some more?

@mounirlamouri
Copy link
Member

Chrome will always show a notification while media is playing. While media is not playing doing something like media.src = ''; will effectively kill the player and reset the session.

@AshleyScirra
Copy link
Author

We want to have audio playback, but no notification. Is this not supported by the spec? Or is it a Chrome issue? Or is it just a total oversight...

@mounirlamouri
Copy link
Member

As you pointed out, the spec doesn't offer a way to disable/de-activate a media session so it's indeed not supported. This is on purpose because browsers will want to keep the notification on. Chrome used to show something about "A tab is playing" before we had media session. We want to make sure the user can come back to the page and kill it if the sound is annoying. It would be hard to convince us otherwise given the easy abuse scenarios.

@AshleyScirra
Copy link
Author

AshleyScirra commented Jun 11, 2019

Well, can't the playback controls at least be removed? There doesn't seem to be any purpose for them in a game.

In particular it seems odd that if you want to disable all the keyboard media keys from affecting audio playback, it actually adds extra non-functional media control buttons in Chrome on Android.

@mounirlamouri
Copy link
Member

That's a good point. For games, we expect Web Audio to be used which doesn't actually create a Media Session. There are some work around an Audio Focus API that will help resolve the games use case but that's not something for the short term.

@AshleyScirra
Copy link
Author

AshleyScirra commented Jun 11, 2019

Web Audio requires that tracks are fully decompressed in memory to play, which can be slow to decode and uses a lot of memory for full music tracks, so it's better to use HTMLAudioElement for its streaming capabilities. So it makes sense for games to use both HTMLAudioElement and Web Audio simultaneously for music and sound effects respectively. But then we get stuck with unwanted media notification/playback controls.

Given the utility of HTMLAudioElement for games but the fact the media session/notification is not appropriate, I think this outlines a reasonable use case for disabling Media Session. Should a new issue be created?

@mounirlamouri
Copy link
Member

I would recommend to have the notification control the background music in this case so the user can still benefit from the notification while it's visible.

I believe that this should be looked at at an audio focus level: https://github.com/WICG/audio-focus

@AshleyScirra
Copy link
Author

AshleyScirra commented Jun 11, 2019

It doesn't seem useful to mute only the music if the sound effects keep playing, because it doesn't affect Web Audio. Normally there is an in-game option to control the music/sound effect playback. If the user wants to stop unwanted playback, then this option doesn't do that for them, since Web Audio keeps going. So it doesn't seem to me to achieve anything anybody wants.

It's not clear to me how audio focus will solve this either - what will that do about this?

BTW if nothing is done, in practice the end result will be lots of games have a media notification with a pause button that does nothing.

@mounirlamouri
Copy link
Member

It doesn't seem useful to mute only the music if the sound effects keep playing, because it doesn't affect Web Audio. Normally there is an in-game option to control the music/sound effect playback. If the user wants to stop unwanted playback, then this option doesn't do that for them, since Web Audio keeps going. So it doesn't seem to me to achieve anything anybody wants.

Well, that's up to you as an author. You could also cut the Web Audio sound when you receive the pause event.

It's not clear to me how audio focus will solve this either - what will that do about this?

The website could ask to not get audio focus and this will also opt out from media session.

@AshleyScirra
Copy link
Author

AshleyScirra commented Jun 13, 2019

Well, that's up to you as an author.

The problem though is that as an author, the result I want doesn't appear to be possible (i.e. just disable Media Session). Your suggestion also means we treat a "pause" button as a "mute" button, which doesn't seem intuitive to the user - if they later resume, it actually unmutes and the playback time is still further ahead, instead of resuming from where it paused like how you'd expect a pause button to work. If we instead pause/resume Web Audio as well, then when resuming they'll hear sound effects for events that occurred earlier in the game and are no longer relevant - possibly including cut scenes, speech or other mid-length clips.

Basically there is an inconsistency here between HTMLAudioElement and Web Audio, and the media session controls aren't appropriate for controlling a game's audio playback.

The website could ask to not get audio focus and this will also opt out from media session.

It's not clear to me looking at the audio focus explainer how this would work. What's the default audio focus and what are the other consequences of opting out of audio focus? What if we want to preserve the default audio focus, and yet not have a media session? It doesn't seem obvious to me that these two states should always go together and not be separately controllable.

@hyunbinseo
Copy link

hyunbinseo commented Dec 7, 2023

Why

I am using multiple <audio> because it removes the hassle of fetching media, caching, etc.

  • BGM
  • Script
  • Effect

When they are played, they show a notification on multiple platforms - macOS, Android, etc.

Specifically, Chrome for Android shows notification on a 5+ sec audio, and this is still true.

Problem

When multiple 5+ sec audios are played simultaneously, the media control paused either one - in this case, the BGM or the script player. The script should not be paused, since it breaks the interaction (in my case).

Workaround

  1. Add all <audio> elements as the page loads.
  2. Assign the non-critical <audio> element to be controlled by the media session.
// Handled on document mount (onMount in SvelteKit)

navigator.mediaSession.metadata = new MediaMetadata({ title: 'BGM' });

// Referenced https://developer.mozilla.org/en-US/docs/Web/API/MediaSession/playbackState

navigator.mediaSession.setActionHandler('play', async () => {
  await bgmPlayer.play();
  navigator.mediaSession.playbackState = 'playing';
});

navigator.mediaSession.setActionHandler('pause', async () => {
  bgmPlayer.pause();
  navigator.mediaSession.playbackState = 'paused';
});

Limitations

When the BGM player is paused and another <audio> is playing

  • Notification shows that an audio is being played.
  • Therefore, the pause button is shown instead.
  • Pressing the pause button does not do anything.
  • Other sounds should be paused / stopped to resume the BGM.

Resuming BGM player does not work in all platforms.

  • macOS + Chrome - launches the music app.
  • macOS + Firefox
  • macOS + Safari
  • Android + Chrome - sometimes pauses the script.
  • Android + Firefox

Note

Check if the media session's playback-state is 'none'. Even when the media is being played and could be paused by the operating system (or the web browser's) media controller, it could be set to none.

MediaSession { metadata: null, playbackState: "none" }
// The browsing context doesn't currently know the current playback state
// Reference https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API

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

No branches or pull requests

3 participants