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

icecast-metadata-player - navigator.mediaSession.metadata not working in iOS #193

Open
blantonl opened this issue Nov 17, 2023 · 3 comments

Comments

@blantonl
Copy link

blantonl commented Nov 17, 2023

setting navigator.mediaSession.metadata on iOS using icecast-metadata-player isn't working. Setting this property provides metadata to the OS to allow iOS to display a user control interface in iOS on the lock screen when a feed is streaming. I'm not dynamically (yet) trying to update this metadata from the stream itself, just setting it when the audio player loads. It works in normal audio tag scenarios fine but not when using icecast-metadata-player

See: https://developer.mozilla.org/en-US/docs/Web/API/MediaSession/metadata

if ("mediaSession" in navigator) {
                console.log("Set Metadata...");
                navigator.mediaSession.metadata = new MediaMetadata({
                    title: "Test Feed",
                    artist: "Broadcastify",
                    album: "Broadcastify Live Audio Feeds",
                    artwork: [
                        {
                            src: "https://s.broadcastify.com/pwa/ios/128.png",
                            sizes: "128x128",
                            type: "image/png",
                        },
                        {
                            src: "https://s.broadcastify.com/pwa/ios/192.png",
                            sizes: "192x192",
                            type: "image/png",
                        },
                        {
                            src: "https://s.broadcastify.com/pwa/ios/256.png",
                            sizes: "256x256",
                            type: "image/png",
                        },
                        {
                            src: "https://s.broadcastify.com/pwa/ios/512.png",
                            sizes: "512x512",
                            type: "image/png",
                        },
                    ],
                });
            }
@blantonl
Copy link
Author

blantonl commented Nov 17, 2023

Quick update to this.

Setting playbackMethod: "html5" gets the mediaSession working and the player showing on the iOS lock screen, however playback stops when iOS safari looses focus and is put into the background (playback just stops at that point when navigating away from Safari)

Edit: html5 background audio is completely broken in 17.0.3 independent of this library.

One other point to note this that the html5 audio "timeupdate" event handler reports a random time using "webaudio", "mediasession" and the default playback methods, however "html5" reports the correct timeupdate for a stream.

@blantonl
Copy link
Author

Ok, good news here. This issue seems to have been resolved in 17.1.1.

You'll need to set playbackMethod: "html5" - but background audio works and the mediaSession.metadata object works great.

@eshaz
Copy link
Owner

eshaz commented Nov 26, 2023

Thanks for entering this issue.

I did some digging, and it looks like there is a known issue / incompatibility (w3c/audio-session#11) with Media Session and Web Audio.

IcecastMetadataPlayer uses the webaudio playback method by default in iOS, since mediasource isn't supported by iOS. The html5 playback method uses the Audio element which is what allows the Media Session to work properly.

The html5 playback method is meant to be used for compatibility and work around reasons (like this one) only. It uses two requests, one for parsing metadata, and another audio request to feed an Audio element. Since there are two requests, it doubles the amount of bandwidth used to listen to a stream in some platforms (I believe iOS merges these duplicate requests into one connection).

I'm thinking I can add a feature in here to allow more control over which playback methods are selected. In cases like this, I think the playback method should be mediasource be for non-iOS browsers, and html5 for iOS, where webaudio is not used. Maybe an option to specify the order in which playback methods are selected would allow this:

// default playback methods
// Chrome, Firefox, Android, Safari desktop will select `mediasource`
// iOS will select `webaudio`
const player = new IcecastMetadataPlayer("https://stream.example.com", {
  playbackMethod: ["mediasource", "webaudio", "html5"]
});

// prefer `html5`, then use `mediasource`, `webaudio`
// all browsers will select `html5` since it's universally supported
const player = new IcecastMetadataPlayer("https://stream.example.com", {
  playbackMethod: "html5"
});

// prefer `mediasource`, then use `html5`, `webaudio`
// Chrome, Firefox, Android, Safari desktop will select `mediasource`
// iOS will select `html5`
const player = new IcecastMetadataPlayer("https://stream.example.com", {
  playbackMethod: ["mediasource", "html5", "webaudio"]
});

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

2 participants