MusicKit JS loses PiP continuity between queued music videos in a background WKWebView

We are trying to play consecutive Apple Music videos in Picture in Picture from a native iOS app.

Our minimal reproduction uses one WKWebView, one MusicKit JS v3 instance and one preloaded queue. There are no parallel players or transitions implemented by our app.

Setup:

  • Inline playback enabled; allowsPictureInPictureMediaPlayback reads true.
  • UIBackgroundModes includes audio.
  • Initial PiP is opened through a user gesture and works correctly.
  • Reproduced on iOS 26.6.2 and iOS 27.0; failure details vary between runs.
await music.setQueue({
  musicVideos: ["1445284008", "1258705880", "290361007"]
});
await music.play();

The user opens PiP, goes to the Home screen and lets the first video finish naturally.

At the queue boundary, MusicKit replaces its HTMLVideoElement. The existing PiP window closes, and the next video does not inherit the presentation.

We also tested requesting PiP once on the new element, after it becomes ready, including a variant waiting for playing. In affected background runs, the element briefly reports the WebKit PiP mode, then receives leavepictureinpicture without enterpictureinpicture. The standard requestPictureInPicture() promise remains pending during observation. Native logs report a failed new PiP start while the source scene is backgrounded.

The equivalent explicit handoff succeeds in the foreground. In one background configuration, the next video continued audibly, while the PiP window still closed. Explicit native playback audio-session configuration did not resolve the continuity issue.

Is there a supported way to:

  1. Preserve the underlying media element/PiP presentation across MusicKit queue items?
  2. Transfer an existing PiP session to the replacement element while backgrounded?
  3. Obtain a reliable error or rejection when native PiP startup fails but the JavaScript promise remains pending?

We can provide a minimal reproducer and correlated JavaScript/native logs.

Answered by DTS Engineer in 908821022

Your event sequence gave me a clear target to test against.

On keeping one media element across queue items: the MusicKit instance reference in MusicKit on the Web documents videoContainerElement. It says you can set it to your own HTMLVideoElement, and "MusicKit will then use that element for video playback, for instance Music Videos." The Events reference also documents mediaElementCreated, which MusicKit fires when "a new media element was created," with the element as the event data. The documentation doesn't say whether an element you supply stays in use across queue items.

On transferring PiP in the background: I don't see a documented way to do that. I built a small test app with two plain <video> elements in a WKWebView, using the configuration you describe. I ran it in iOS 27.0 with the app in the background:

  • With no element in PiP, requestPictureInPicture() rejected immediately with NotAllowedError: "The request is not triggered by a user activation."
  • With the first element still in PiP, requestPictureInPicture() on the second element stayed pending. The PiP window stayed on the first element, and no enterpictureinpicture or leavepictureinpicture event fired for the second.

On the pending promise: in the W3C Picture-in-Picture specification, every path through the request steps either resolves or rejects the promise that requestPictureInPicture() returns. When you have a chance, please use Feedback Assistant to file a bug report about the promise that never settles. Attach your minimal reproducer and logs. If you file it, please post the Feedback number here so I can make sure it gets to the right team.

If you're not familiar with how to file bug reports, take a look at Bug Reporting: How and Why?

Your event sequence gave me a clear target to test against.

On keeping one media element across queue items: the MusicKit instance reference in MusicKit on the Web documents videoContainerElement. It says you can set it to your own HTMLVideoElement, and "MusicKit will then use that element for video playback, for instance Music Videos." The Events reference also documents mediaElementCreated, which MusicKit fires when "a new media element was created," with the element as the event data. The documentation doesn't say whether an element you supply stays in use across queue items.

On transferring PiP in the background: I don't see a documented way to do that. I built a small test app with two plain <video> elements in a WKWebView, using the configuration you describe. I ran it in iOS 27.0 with the app in the background:

  • With no element in PiP, requestPictureInPicture() rejected immediately with NotAllowedError: "The request is not triggered by a user activation."
  • With the first element still in PiP, requestPictureInPicture() on the second element stayed pending. The PiP window stayed on the first element, and no enterpictureinpicture or leavepictureinpicture event fired for the second.

On the pending promise: in the W3C Picture-in-Picture specification, every path through the request steps either resolves or rejects the promise that requestPictureInPicture() returns. When you have a chance, please use Feedback Assistant to file a bug report about the promise that never settles. Attach your minimal reproducer and logs. If you file it, please post the Feedback number here so I can make sure it gets to the right team.

If you're not familiar with how to file bug reports, take a look at Bug Reporting: How and Why?

Thanks for your answer. I posted a report Sept 19 : FB24853723 I will add a minimal reproducer shortly.

I updated the feedback report with a POC iOS App

To make it short, our biggest issues for our upcoming iPhone Duo App right now are :

  • not being able to get a playlist of Apple Music video clips to play in PiP mode while the user is not in the App.
  • not being able to change the playing video currently in PiP while the App is in the background.

Which is significantly lowering interest and UX for a music video player.