Reputation: 944
This is something I've researched off and on for literal years and have never been able to find the answer. I found the MediaSession api which works for populating song data but the next track and previous track action handlers don't make the next/ previous buttons appear in the iOS control center.
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: '',
artist: '',
album: '',
artwork: []
});
navigator.mediaSession.setActionHandler('play', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('pause', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('stop', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('seekbackward', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('seekforward', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('seekto', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('previoustrack', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('nexttrack', () => { /* Code excerpted. */ });
navigator.mediaSession.setActionHandler('skipad', () => { /* Code excerpted. */ });
}
I found the AudioContext api which sounded promising because apple mentions it in their docs, but then the MediaSession metadata stops working and the next/ previous track buttons still don't appear.
context = new AudioContext();
audioElement = document.querySelector('audio');
const track = context.createMediaElementSource(audioElement);
track.connect(context.destination);
audioElement.play()
Does anyone have experience with this? I attached some images that show what I'm trying to accomplish, the first image shows the controls that just using the MediaSession api gives me(skip forward/back 10 seconds), and the second image shows the controls that the Spotify web app is able to get(forward/back buttons).
For the life of me I cannot get the next/ previous track buttons to populate on iOS.
Upvotes: 4
Views: 1549
Reputation: 31
I've solved this problem by setting the action handlers once my audio
element was playing using the playing
event.
This was tested on my iPhone and iPad, both running iOS/iPadOS 17.3.1.
skip
is a custom function.
audio.addEventListener('playing', () => {
navigator.mediaSession.setActionHandler('play', () => audio.play());
navigator.mediaSession.setActionHandler('pause', () => audio.pause());
navigator.mediaSession.setActionHandler('previoustrack', () => {
skip(-1);
audio.play();
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
skip(1);
audio.play();
});
navigator.mediaSession.setActionHandler('seekto', (details) => {
if (details.seekTime) {
audio.currentTime = details.seekTime;
}
});
});
Upvotes: 2
Reputation: 796
It seems it's a recent change in iOS and ipadOS that you cannot have both seekbackward, seekforward
and previoustrack, nexttrack
together. So you need to choose that you want to have next and previous track actions or seek backward and forward on iOS.
Upvotes: 3