fix(preview): flag unplayable media when previewing a standalone asset#96
fix(preview): flag unplayable media when previewing a standalone asset#96ctrlaltking wants to merge 1 commit into
Conversation
previewAsset() created AVPlayerItem(url:) directly with no error handling, so a corrupt or unsupported source file just left the preview blank/frozen with no feedback. The timeline composition path already detects this (offlineMediaRefs/unprocessableMediaRefs via CompositionBuilder) and surfaces a "Couldn't Prepare Media" overlay — this path never ran for assets previewed before being placed on the timeline. Probe the asset's tracks after swapping in the player item and mark it unprocessable on failure, reusing the existing offline/unprocessable UI instead of leaving a silent blank player.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7c99a33. Configure here.
| Log.preview.error("previewAsset: media unplayable assetId=\(assetId.prefix(8))") | ||
| editor.unprocessableMediaRefs.insert(assetId) | ||
| } | ||
| } |
There was a problem hiding this comment.
Stale media probe race
Medium Severity
Each call to verifyAssetPlayable starts a new unstructured Task without cancelling earlier probes. openPreviewTab always calls activateTab, so re-opening the same asset can run overlapping loadTracks checks. A slower, older task can finish last and update unprocessableMediaRefs after a newer probe, showing or hiding the unplayable overlay incorrectly.
Reviewed by Cursor Bugbot for commit 7c99a33. Configure here.


Summary
VideoEngine.previewAsset()buildsAVPlayerItem(url: asset.url)directly with no error handling. If the source file can't actually decode (corrupt, truncated, unsupported codec variant), the preview just sits blank/frozen with no feedback anywhere — no log, no UI state change.CompositionBuilderprobes each clip's tracks and records failures intoofflineMediaRefs/unprocessableMediaRefs, whichPreviewContainerViewuses to show a "Couldn't Prepare Media" overlay with an explanation and a report button. That path never ran for an asset previewed standalone (before being placed on the timeline).AVURLAsset(url:).loadTracks(withMediaType: .video)on a garbage/corrupt file throwsAVErrorFailedDependenciesKey "Cannot Open"— exactly the case that silently fails today.Fix
After swapping in the player item in
previewAsset(), probe the asset's tracks in the background. On failure, insert the asset id intoeditor.unprocessableMediaRefs, reusing the existing offline/unprocessable UI instead of leaving a silent blank player.Test plan
swift build— clean buildswift test— full suite passes (one pre-existing failure inCompositionBuilderTests.fractionalSpeedAudioUsesTruncatedSourceFramesForCompositionInsertionconfirmed present on unmodifiedmaintoo, unrelated to this change)AVURLAsset.loadTracksthrows on a corrupt file with a video extension, matching the failure mode this fix detectsNote
Low Risk
Small, preview-only change that toggles existing editor UI state; no auth, export, or timeline composition logic is modified.
Overview
Standalone media previews no longer fail silently when
AVPlayerItem(url:)cannot decode the file. After swapping in the player item inpreviewAsset(), the engine asynchronously probesAVURLAsset.loadTracks(withMediaType:)for the correct audio or video track.If decoding fails or no track is found, the asset id is added to
editor.unprocessableMediaRefs(with a preview log); if the file becomes playable, the id is removed. That reuses the same unprocessable/offline overlay the timeline composition path already drives viaCompositionBuilder, which never ran for library-only asset preview.Reviewed by Cursor Bugbot for commit 7c99a33. Bugbot is set up for automated code reviews on this repo. Configure here.