regosen / Gapless-5

Gapless JavaScript audio player using HTML5 and WebAudio
MIT License
143 stars 23 forks source link

Incompatibility with MediaSession API #54

Open gonzaloarca opened 11 months ago

gonzaloarca commented 11 months ago

Describe the bug When the player uses HTML5 audio, the MediaSession API works properly in Chrome. This includes setting metadata, such as track title, artist, artwork etc. in the media controls, as well as setting the callbacks for each player event. However, when the libray switches to WebAudio, some of these callbacks stop working (such as pausing, for some reason), and eventually, the MediaSession controls disappear after some time of WebAudio playback (especially when a track is played from WebAudio from the start).

I did some research and stumbled upon this StackOverflow post, where a user needs to show MediaSession controls although there's no audio playing. The docs mention the following:

Note that: Notifications are only shown for media over five seconds in length. There is no notification for audio from the Web Audio API unless it is played back via an audio element. With the Media Session API, you can customize media notifications by providing metadata for the media your web app is playing. This API also allows you to handle media related events such as seeking or track changing which may come from notifications or media keys.

In the end, the author of the post allegedly managed to fix it by using an HTML5 <audio/> element with an audio file that's completely silent and looping it.

Now, I'm not sure if this is a bug in the library that can be easily fixed, or if this was never considered in the first place. In any case, maybe that post could help you achieve it, or maybe you can think of another, more elegant solution. I'll be forever grateful if a solution can be found!

johnnyshankman commented 2 weeks ago

+1 would love this feature

johnnyshankman commented 2 weeks ago

Can confirm that the silent audio trick works as long as you pause/play it in sync with the gapless 5 player. You can implement this on your own without gapless 5 doing it for you for now.

Note: It has to be a silent mp3 of at least like 2-5s in length otherwise the media session seems to just ignore it entirely as a sound effect.

Screenshot 2024-11-11 at 9 33 21 PM

Then handle the actions and metadata yourself:

    navigator.mediaSession.setActionHandler('previoustrack', playPreviousSong);
    navigator.mediaSession.setActionHandler('nexttrack', playNextSong);
    navigator.mediaSession.setActionHandler('play', () => {
      setPaused(false);
    });
    navigator.mediaSession.setActionHandler('pause', () => {
      setPaused(true);
    });
    navigator.mediaSession.setPositionState({
      duration: song.duration
      playbackRate: 1,
      position: 0
    });

If you want to see a live example check out my open-source music player for osx: