fix: iOS audio playback, background handling, and clock sync fixes#102
Open
hayupadhyaya wants to merge 2 commits intomusic-assistant:mainfrom
Open
fix: iOS audio playback, background handling, and clock sync fixes#102hayupadhyaya wants to merge 2 commits intomusic-assistant:mainfrom
hayupadhyaya wants to merge 2 commits intomusic-assistant:mainfrom
Conversation
- Replace synchronized() with Mutex.withLock{} in AudioStreamManager.kt
(synchronized is JVM-only; suspend functions use withLock, close() uses runBlocking)
- Wire updateNowPlaying() in MainDataSource to push track metadata, artwork,
elapsed time and playback rate to the iOS Now Playing center on every
local player state change (~500 ms cadence via position tracker loop)
- Embed WebRTC.framework into the app bundle in the Xcode build phase script
and sign it with $EXPANDED_CODE_SIGN_IDENTITY so dyld can find it at
runtime (without this the app crashes immediately on launch)
- Fix no-audio bug: MessageDispatcher and AudioStreamManager each had independent TimeSource.Monotonic.markNow() epochs; ClockSynchronizer now owns the shared startMark and exposes getCurrentTimeMicros() so serverLoopOriginLocal and currentLocalTime are always in the same domain - Add AVAudioSession interruption + route-change handlers to NativeAudioController; auto-resumes playback after phone calls/Siri - Add writeRawPcmNSData(NSData) for efficient Kotlin→Swift PCM transfer via usePinned bulk copy (avoids per-byte Swift interop loop) - Fix DataChannelWrapper binary fast path: first-byte check instead of full decodeToString() on every audio chunk at 50-100/sec - Fix OAuthHandler: open OAuth URLs in Safari instead of throwing UnsupportedOperationException - Fix SystemAppearance: apply overrideUserInterfaceStyle to all windows - Fix Config.xcconfig: rename BUNDLE_ID to PRODUCT_BUNDLE_IDENTIFIER - Fix project.pbxproj: copy compose-resources into app bundle so Compose Multiplatform assets (images, fonts) resolve at runtime - Update README: iOS features section + building from source - Update .claude docs: mark iOS volume, background playback, and no-audio bug as resolved (pending end-to-end tests) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
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.
Fix no-audio bug (clock sync time-base mismatch) —
MessageDispatcherandAudioStreamManagereach had independentTimeSource.Monotonic.markNow()epochs.ClockSynchronizer.serverLoopOriginLocalwas calibrated using MessageDispatcher's time domain, butAudioStreamManager.getCurrentTimeMicros()used a different epoch, causing all chunktimestamps to appear perpetually early and no audio to play. Fixed by moving the shared
startMarkintoClockSynchronizerand having both classes delegate toclockSynchronizer.getCurrentTimeMicros().Fix iOS background audio — Added
AVAudioSessioninterruption and route-changeNotificationCenterobservers toNativeAudioController. Playback now auto-resumes after phone calls,Siri interruptions, and handles headphone/Bluetooth disconnects correctly.
Fix iOS volume control —
getCurrentSystemVolume()was returning a hardcoded value. Now reads the real system volume viaAVAudioSession.sharedInstance().outputVolume.Efficient Kotlin→Swift PCM data transfer — Added
writeRawPcmNSData(NSData)toNativeAudioControllerandPlatformAudioPlayer. Kotlin side now usesusePinned/addressOfbulk copyto convert
ByteArray→NSDatain a single memcpy instead of a per-byte Swift interop loop.DataChannelWrapper binary fast path — Replaced full
decodeToString()on every incoming message with a first-byte check ({/[) to distinguish text vs binary frames. Audio chunksarrive at 50–100/sec so this avoids a significant amount of unnecessary UTF-8 decoding.
Fix OAuthHandler — Was throwing
UnsupportedOperationException. Now opens the OAuth URL in Safari viaUIApplication.openURL.Fix SystemAppearance — Was a no-op stub. Now correctly applies
overrideUserInterfaceStyleto all windows for dark/light mode support.Fix compose-resources not bundled — Compose Multiplatform assets (images, fonts) were not being copied into the
.appbundle, causing aMissingResourceExceptioncrash on launch. Addeda shell script step to the Xcode build phase to copy from
composeApp/build/kotlin-multiplatform-resources/aggregated-resources/into the app bundle.Fix Config.xcconfig — Renamed
BUNDLE_IDtoPRODUCT_BUNDLE_IDENTIFIERto match the variable name expected by the pbxproj.Docs — Updated README with iOS features and building-from-source section. Updated
.claude/status docs to reflect resolved issues (pending end-to-end device tests).Test plan
MissingResourceException