stride3d/stride · error · InvalidOperationException

PauseMedia failed: MediaCodecScheduler is null

Error message

PauseMedia failed: MediaCodecScheduler is null

What it means

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.

Solutions

  1. Guard Pause calls: only invoke when the backend is initialized (mediaSynchronizer != null)
  2. Fix the earlier Initialize failure that left the backend uninitialized
  3. Null-check or state-check in the UI handler before calling Pause
  4. Do not call Pause after Dispose; track backend state in the component

Example fix

// before
backend.Pause(); // throws when uninitialized
// after
if (backend.IsInitialized) backend.Pause();
Defensive patterns

Strategy: validation

Validate before calling

if (backend.IsInitialized) backend.Pause();

Type guard

bool CanPause(MediaCodecVideoBackend b) => b.IsInitialized;

Try / catch

try { backend.Pause(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("PauseMedia failed"))
{ /* ignore or track that no video is loaded */ }

Prevention

When it happens

Trigger: 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.

Common situations: Pause buttons firing when no video is loaded; pause-after-error paths; disposing the backend on scene exit while UI still references it.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/b646f6837d96e2a1. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Video/Backends/MediaCodecVideoBackend.cs:161

        if (rgbaScratch != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(rgbaScratch);
            rgbaScratch = IntPtr.Zero;
            rgbaScratchSize = 0;
        }
    }

    public override void Play()
    {
        if (mediaSynchronizer == null || mediaCodecVideoExtractor == null)
            throw new InvalidOperationException("PlayMedia failed: MediaCodecScheduler is null");
        mediaSynchronizer.Play();
    }

    public override void Pause()
    {
        if (mediaSynchronizer == null)
            throw new InvalidOperationException("PauseMedia failed: MediaCodecScheduler is null");
        mediaSynchronizer.Pause();
    }

    public override void Stop()
    {
        mediaSynchronizer.Stop();
    }

    public override void Seek(TimeSpan time)
    {
        if (mediaSynchronizer == null)
            throw new InvalidOperationException("Seek failed: MediaCodecScheduler is null");
        mediaSynchronizer.Seek(time);
    }

    public override void SetPlaybackSpeed(float speed) => mediaSynchronizer.SpeedFactor = speed;

    public override void SetAudioVolume(float volume)

View on GitHub (pinned to 96fad776d2)