{"record":{"id":"0d82ef3fac768a99","repo":"stride3d/stride","slug":"avassetreader-startreading-audio-failed-err-null-err","errorCode":null,"errorMessage":"AVAssetReader.StartReading (audio) failed: {(err != null ? err.LocalizedDescription : \"unknown\")}","messagePattern":"AVAssetReader\\.StartReading \\(audio\\) failed: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Audio/StreamedBufferSoundSource.AVFoundation.cs","lineNumber":118,"sourceCode":"            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);\n        audioReader.AddOutput(audioOutput);\n        if (!audioReader.StartReading())\n        {\n            var err = audioReader.Error;\n            throw new InvalidOperationException(\n                $\"AVAssetReader.StartReading (audio) failed: {(err != null ? err.LocalizedDescription : \"unknown\")}\");\n        }\n    }\n\n    private void DisposeReader()\n    {\n        audioOutput?.Dispose();\n        audioOutput = null;\n        audioReader?.Dispose();\n        audioReader = null;\n    }\n\n    private bool ExtractSomeAudioData(out bool endOfFile)\n    {\n        endOfFile = audioExtractionDone;\n        if (audioExtractionDone || audioOutput == null)\n            return false;\n","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Audio/StreamedBufferSoundSource.AVFoundation.cs#L100-L136","documentation":"StreamedBufferSoundSource (AVFoundation backend) throws this when AVAssetReader.StartReading() fails after the audio output has been attached. The reader cannot begin producing decoded audio frames, so streaming cannot proceed. The AVAssetReader.Error LocalizedDescription is embedded to reveal the underlying cause (format mismatch, corrupted asset, expired track, etc.).","triggerScenarios":"Calling InitializeMediaExtractor or SeekInternalImpl on macOS/iOS builds with an audio file whose audioTrack was invalidated or whose AVAssetReaderAudioMixOutput settings (AVFormatIDKey/AVNumberOfChannelsKey) are unsupported by the decoder; StartReading returns false and the exception is thrown.","commonSituations":"Loading an audio file with a sample-rate/channel-count conversion AVFoundation cannot perform; reading a DRM-protected or corrupt media file; seeking on a disposed/re-created reader after the asset track was released; wrong outputSettings keys passed to the reader.","solutions":["Inspect the embedded LocalizedDescription in the exception message for the concrete AVFoundation reason","Verify the source file is decodable (playable in AVPlayer / afinfo) before creating the reader","Check that the reader output settings (outputSettings dict on AVAssetReaderAudioMixOutput) request a supported format like Mono16 or Stereo16 PCM","Re-create the reader (DisposeReader + re-init) after seeking instead of reusing a reader whose StartReading already failed","Ensure the asset still has an audio track (check track.Count > 0 and mediaType == AVMediaType.Audio) before adding the output"],"exampleFix":"// before\nvar settings = new AVAudioSettingsFloat { AVFormatIDKey = (int)AVAudioFormat.ThreeSixty }; // unsupported\naudioReader.AddOutput(new AVAssetReaderAudioMixOutput(new[] { audioTrack }, settings));\naudioReader.StartReading();\n// after\nvar settings = new AVAudioSettingsFloat\n{\n    AVFormatIDKey = (int)CMAudioFormatID.LinearPCM,\n    AVLinearPCMBitDepthKey = 16,\n    AVLinearPCMIsFloatKey = false,\n    AVLinearPCMIsBigEndianKey = false,\n    AVNumberOfChannelsKey = 1\n};\nvar output = new AVAssetReaderAudioMixOutput(new[] { audioTrack }, settings);\naudioReader.AddOutput(output);\nif (!audioReader.StartReading())\n    Logger.Error($\"StartReading failed: {audioReader.Error?.LocalizedDescription}\");","handlingStrategy":"try-catch","validationCode":"// AVFoundation/macOS\nif (audioTrack == null || asset.Tracks.Length == 0)\n    throw new InvalidOperationException(\"Asset has no audio track\");\nvar playable = asset.IsPlayable;\nif (!playable) throw new InvalidOperationException(\"Asset not playable\");","typeGuard":"bool HasReadableAudioTrack(AVAssetReader reader) => reader != null && reader.Status == AVAssetReaderStatus.Unknown && reader.Error == null;","tryCatchPattern":"try\n{\n    source = new StreamedBufferSoundSource(path, services);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"StartReading\"))\n{\n    Logger.Error($\"Audio reader init failed: {ex.Message}\");\n    source = null; // fall back to non-streamed sound\n}","preventionTips":["Check asset tracks and playability before constructing the reader","Use standard PCM output settings (16-bit linear PCM) supported by all devices","Test with known-good media files (afinfo/ffprobe) before shipping","Re-create readers after seek instead of reusing failed ones"],"tags":["audio","avfoundation","ios","macos","streaming"],"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"}