{"record":{"id":"972cea3d8236ec30","repo":"stride3d/stride","slug":"avassetreader-audio-create-failed-error-localizeddescription","errorCode":null,"errorMessage":"AVAssetReader (audio) create failed: {error.LocalizedDescription}","messagePattern":"AVAssetReader \\(audio\\) create failed: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Audio/StreamedBufferSoundSource.AVFoundation.cs","lineNumber":95,"sourceCode":"        audioAsset = null;\n        audioTrack = null;\n\n        if (audioTempFilePath != null && File.Exists(audioTempFilePath))\n        {\n            try { File.Delete(audioTempFilePath); } catch { /* best-effort */ }\n        }\n        audioTempFilePath = null;\n    }\n\n    private void CreateAudioReader(TimeSpan startTime)\n    {\n        DisposeReader();\n        if (audioAsset == null || audioTrack == null)\n            return;\n\n        audioReader = AVAssetReader.FromAsset(audioAsset, out var error);\n        if (error != null)\n            throw new InvalidOperationException($\"AVAssetReader (audio) create failed: {error.LocalizedDescription}\");\n\n        if (startTime > TimeSpan.Zero)\n        {\n            var startCMTime = new CMTime((long)(startTime.TotalMilliseconds), 1000);\n            audioReader.TimeRange = new CMTimeRange { Start = startCMTime, Duration = CMTime.PositiveInfinity };\n        }\n\n        // 16-bit signed LE interleaved PCM — the format Stride.Audio consumes downstream.\n        var settings = new NSMutableDictionary\n        {\n            [AVAudioSettings.AVFormatIDKey] = NSNumber.FromUInt32((uint)AudioFormatType.LinearPCM),\n            [AVAudioSettings.AVLinearPCMBitDepthKey] = NSNumber.FromInt32(16),\n            [AVAudioSettings.AVLinearPCMIsBigEndianKey] = NSNumber.FromBoolean(false),\n            [AVAudioSettings.AVLinearPCMIsFloatKey] = NSNumber.FromBoolean(false),\n            [AVAudioSettings.AVLinearPCMIsNonInterleaved] = NSNumber.FromBoolean(false),\n        };\n\n        audioOutput = new AVAssetReaderAudioMixOutput(new[] { audioTrack }, settings);","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Audio/StreamedBufferSoundSource.AVFoundation.cs#L77-L113","documentation":"On iOS/macOS, StreamedBufferSoundSource.CreateAudioReader builds an AVAssetReader for the audio track of an asset. If AVAssetReader.FromAsset reports a non-null NSError, the reader could not be created and the method throws with the OS's localized description. Without a reader the streamed audio cannot be decoded.","triggerScenarios":"Initializing the media extractor or seeking (SeekInternalImpl) on an AVFoundation-backed streamed sound when AVAssetReader creation fails — asset URL points to a missing/unreadable file, the asset has no compatible audio track, or the file format is not decodable by AVFoundation.","commonSituations":"Media file not copied into the app bundle (missing BundleResource build action) so the asset URL is invalid, DRM-protected or unsupported codec/container (e.g. some WMA/FLAC variants), file deleted from the sandbox after being picked, corrupted download.","solutions":["Read error.LocalizedDescription from the exception to identify the OS-level cause (missing file vs. undecodable format).","Confirm the media file is deployed as a BundleResource and reachable via the URL passed to the sound loader.","Re-encode the audio to a broadly supported format (AAC/M4A or CBR MP3) if the codec is unsupported or DRM-protected.","Re-copy or re-download the file if it was removed or corrupted, then retry playback."],"exampleFix":"// before\nvar sound = Sound.LoadStreamed(services, \"music/track.wma\"); // AVAssetReader fails on unsupported codec\n// after\n// ship music/track.m4a (AAC) as BundleResource instead\nvar sound = Sound.LoadStreamed(services, \"music/track.m4a\");\ntry { sound.CreateInstance(listener); }\ncatch (InvalidOperationException ex) { Log.Error($\"Audio open failed: {ex.Message}\"); }","handlingStrategy":"try-catch","validationCode":"// before loading, on iOS/macOS\nvar url = NSBundle.MainBundle.GetUrlForResource(\"track\", \"m4a\", \"music\");\nif (url == null || !NSFileManager.DefaultManager.FileExists(url.Path))\n    Log.Error(\"Audio asset missing from app bundle\");","typeGuard":"bool IsPlayableMediaAsset(NSUrl assetUrl) =>\n    assetUrl != null && NSFileManager.DefaultManager.FileExists(assetUrl.Path);\n","tryCatchPattern":"try\n{\n    var sound = Sound.LoadStreamed(services, mediaUrl);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"AVAssetReader\"))\n{\n    Log.Error($\"Media cannot be decoded on this device: {ex.Message}\");\n    // fallback: use a pre-encoded AAC copy or skip audio\n}","preventionTips":["Deploy media as BundleResource and verify via NSBundle URL lookup before playback.","Ship audio in AVFoundation-friendly formats (AAC/M4A, CBR MP3).","Avoid DRM-protected or exotic-codec files for streamed playback.","Validate user-picked files by probing them with AVAsset immediately after selection, before storing the URL."],"tags":["ios","macos","audio","avfoundation","media"],"backgroundTag":"file-read-failed","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}