fix: don't hang the main thread on live streams during chapter inspection - #106
fix: don't hang the main thread on live streams during chapter inspection#106pke wants to merge 3 commits into
Conversation
…tion The metadata completion read `pendingAsset.duration` without ever async-loading it. An unloaded AVAsset property getter falls back to a synchronous XPC fetch to mediaserverd — and for indefinite-duration (live) streams, iOS 26 answers that query only after an internal ~20s timeout. Since the completion runs on the main thread, every playback start of a SHOUTcast/Icecast stream froze the entire app for ~20s (queued touches, watchdog 0x8BADF00D kills when backgrounded). Load `duration` together with the other inspected keys, and skip chapter inspection entirely for indefinite assets — live streams have no chapters, and their metadata arrives via timed metadata anyway. Watchdog backtrace mid-hang (iPhone 13 Pro, iOS 26.5): mach_msg2_trap xpc_connection_send_message_with_reply_sync CoreMedia FigXPCConnectionSendSyncMessageCreatingReply MediaToolbox remoteXPCAsset_CopyPropertyAndBlockageWarning AVFCore -[AVAsset(AVAssetChapterInspection) _loadChapterInfo] AVFCore -[AVAsset(AVAssetChapterInspection) availableChapterLocales]
Making the reads async-loaded was not enough: AVAsset serializes its property loading per asset, so requesting the metadata keys before "playable" queued item creation — and audio start — behind the same ~20s live-stream probe. Move the inspection to the end of the playable completion: playback starts immediately, chapters/common metadata resolve whenever the daemon answers (instantly for files, late and irrelevant for live streams).
|
Pushed a second commit after on-device verification: async-loading alone freed the UI but audio start was still delayed ~20s — AVAsset serializes property loading per asset, so the metadata request queued the |
…duration Requesting the metadata keys anywhere near playback start still stalls audio on live streams: AVAsset serializes property loading, so the ~20s live-stream probe queues either the playable key or the item's own preparation behind it. The player item's observed duration tells live from file without touching the asset — inspect chapters and common metadata only once a finite duration is reported, and never for indefinite (live) streams.
|
Final design, verified on device (iPhone 13 Pro, iOS 26.5): metadata inspection is now deferred until the player item reports a finite duration. Any earlier trigger point still delayed audio — AVAsset serializes property loading, so a pre-playable request queued the |
Fixes #105.
The metadata completion reads
pendingAsset.durationwithout it ever being async-loaded. An unloadedAVAssetproperty getter falls back to a synchronous XPC fetch to mediaserverd — and for indefinite-duration (live) streams, iOS 26 answers that query only after an internal ~20s timeout. The completion runs on the main thread, so every playback start of a SHOUTcast/Icecast stream freezes the whole app for ~20 seconds (touches queue up; backgrounding mid-hang gets the app watchdog-killed with 0x8BADF00D). Older iOS versions answered immediately, which is why this surfaced only recently.Two changes, no API surface:
"duration"to the async-loaded metadata keys, andVerified on device (iPhone 13 Pro, iOS 26.5) against a live SHOUTcast stream: app start went from a 20.11s Severe Hang (Instruments) to instant, with ICY timed metadata unaffected. Full analysis and the captured watchdog backtrace in #105.