{"record":{"id":"b646f6837d96e2a1","repo":"stride3d/stride","slug":"pausemedia-failed-mediacodecscheduler-is-null","errorCode":null,"errorMessage":"PauseMedia failed: MediaCodecScheduler is null","messagePattern":"PauseMedia failed: MediaCodecScheduler is null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Video/Backends/MediaCodecVideoBackend.cs","lineNumber":161,"sourceCode":"        if (rgbaScratch != IntPtr.Zero)\n        {\n            Marshal.FreeHGlobal(rgbaScratch);\n            rgbaScratch = IntPtr.Zero;\n            rgbaScratchSize = 0;\n        }\n    }\n\n    public override void Play()\n    {\n        if (mediaSynchronizer == null || mediaCodecVideoExtractor == null)\n            throw new InvalidOperationException(\"PlayMedia failed: MediaCodecScheduler is null\");\n        mediaSynchronizer.Play();\n    }\n\n    public override void Pause()\n    {\n        if (mediaSynchronizer == null)\n            throw new InvalidOperationException(\"PauseMedia failed: MediaCodecScheduler is null\");\n        mediaSynchronizer.Pause();\n    }\n\n    public override void Stop()\n    {\n        mediaSynchronizer.Stop();\n    }\n\n    public override void Seek(TimeSpan time)\n    {\n        if (mediaSynchronizer == null)\n            throw new InvalidOperationException(\"Seek failed: MediaCodecScheduler is null\");\n        mediaSynchronizer.Seek(time);\n    }\n\n    public override void SetPlaybackSpeed(float speed) => mediaSynchronizer.SpeedFactor = speed;\n\n    public override void SetAudioVolume(float volume)","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Video/Backends/MediaCodecVideoBackend.cs#L143-L179","documentation":"MediaCodecVideoBackend.Pause was called while mediaSynchronizer is null, i.e. the backend was never successfully initialized. Pausing requires the synchronizer created during Initialize; the backend throws instead of no-op.","triggerScenarios":"Calling Pause before Initialize; Pause after Dispose; Initialize previously failed (e.g. audio engine error) leaving mediaSynchronizer null; UI code wiring Pause to a button regardless of backend state.","commonSituations":"Pause buttons firing when no video is loaded; pause-after-error paths; disposing the backend on scene exit while UI still references it.","solutions":["Guard Pause calls: only invoke when the backend is initialized (mediaSynchronizer != null)","Fix the earlier Initialize failure that left the backend uninitialized","Null-check or state-check in the UI handler before calling Pause","Do not call Pause after Dispose; track backend state in the component"],"exampleFix":"// before\nbackend.Pause(); // throws when uninitialized\n// after\nif (backend.IsInitialized) backend.Pause();","handlingStrategy":"validation","validationCode":"if (backend.IsInitialized) backend.Pause();","typeGuard":"bool CanPause(MediaCodecVideoBackend b) => b.IsInitialized;","tryCatchPattern":"try { backend.Pause(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"PauseMedia failed\"))\n{ /* ignore or track that no video is loaded */ }","preventionTips":["State-check before pause/stop calls","Handle Pause on dead backends gracefully in UI wiring","Track backend state so Dispose invalidates dependent UI actions"],"tags":["android","mediacodec","video","lifecycle"],"backgroundTag":"invalid-state-transition","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"}