Add background audio and lock screen player (iOS) - #2
Draft
webguy-nz wants to merge 1 commit into
Draft
Conversation
Populate MPNowPlayingInfoCenter and register MPRemoteCommandCenter handlers so playback appears on the lock screen, in Control Center and in the Dynamic Island, with working transport controls. play() accepts optional title / artist / artwork. Remote artwork is fetched off the main thread and applied when it arrives, so playback never waits on it. A new RemoteCommand event reports lock screen presses back to PHP so in-app UI can reconcile; the native side has already applied the command. Live streams needed specific handling, verified on an iPhone 15 Pro against a live HLS radio stream: - A source with a non-finite duration is published with IsLiveStream, which makes iOS render a LIVE badge with no scrubber. It also makes the system show a stop button rather than pause/play, so pauseCommand is never delivered for live audio and a halt arrives as stopCommand. - Remote stop therefore releases the player, since a live buffer is stale the moment it stops, but keeps the Now Playing card so the user can start again from the lock screen. Deactivating the audio session here would hand the Now Playing slot to whatever played previously and the card would vanish. - Remote play restarts from the last source when the player has been released, and seeks to the live edge when it is merely paused, rather than resuming a stale buffer. The audio background mode is deliberately left to the consuming app rather than declared in the manifest: Apple rejects apps that claim a background mode they do not use, and a video-only consumer must not inherit it. The README documents the one-line config opt-in, and a test pins the omission.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Populates
MPNowPlayingInfoCenterand registersMPRemoteCommandCenterhandlers, so playback appears on the lock screen, in Control Center and in the Dynamic Island with working transport controls.iOS only. There is no Android counterpart in this PR — the Kotlin side is untouched.
API
play()accepts optionaltitle,artistandartwork:Remote artwork is fetched off the main thread and applied when it arrives, so playback never waits on it. Omitted keys are not sent, so existing
play()calls are unaffected.A new
RemoteCommandevent reports lock screen presses back to PHP so in-app UI can reconcile. The native side has already applied the command by the time the event fires — handlers exist to sync UI, not to perform the action.Live streams
Verified on a physical iPhone 15 Pro against a live HLS radio stream. Live sources needed specific handling:
IsLiveStream, which makes iOS render a LIVE badge with no scrubber. It also makes the system show a stop button rather than pause/play, sopauseCommandis never delivered for live audio and a halt arrives asstopCommand.Background audio is left to the consuming app
The
audiobackground mode is deliberately not declared in the manifest: Apple rejects apps that claim a background mode they don't use, and a video-only consumer must not inherit it. Consumers opt in from their ownconfig/nativephp.php:The README documents this, and a test pins the omission so it can't be added back by accident.
This is the main design decision I'd like a second opinion on before this comes out of draft — happy to flip it to declared-by-default if you'd rather the plugin own it.
Testing
vendor/bin/pest— 42 passed, 126 assertions. New coverage intests/NowPlayingTest.phpplus a manifest test for the background-mode omission. The 2 warnings on the existing off-device bridge tests are pre-existing (no bridge listening on127.0.0.1:3002outside the runtime).Manually verified on an iPhone 15 Pro: lock screen, Control Center and Dynamic Island transport controls against both a live HLS stream and a finite-duration file.