stride3d/stride · error · InvalidOperationException
Seek failed: MediaCodecScheduler is null
Error message
Seek failed: MediaCodecScheduler is null
What it means
Thrown by MediaCodecVideoBackend.Seek when the underlying media synchronizer has not been created (or has been released) when a seek is requested. The library treats a seek on an un-initialized/disposed backend as a programming error, so it throws immediately rather than silently ignoring the request. The message mentions 'MediaCodecScheduler' (the synchronizer/scheduler object) even though the guard checks mediaSynchronizer.
Solutions
- Ensure Initialize completed successfully before wiring UI seek handlers to the backend
- Guard Seek call sites: only call when the backend reports it is initialized/playing
- Check that teardown/Dispose nulls or blocks Seek, and unsubscribe UI events on dispose
- Catch InvalidOperationException around Seek and ignore/log if not yet initialized
Example fix
// before
videoBackend.Seek(newPosition); // may throw if not initialized
// after
if (videoBackend.IsInitialized)
videoBackend.Seek(newPosition);
else
Logger.Warning("Seek ignored: backend not initialized"); Defensive patterns
Strategy: try-catch
Validate before calling
if (videoBackend == null || !videoBackend.IsInitialized)
return; // don't attempt to seek yet Type guard
static bool CanSeek(MediaCodecVideoBackend b) => b is { } && b.IsInitialized && !b.IsDisposed; Try / catch
try
{
videoBackend.Seek(position);
}
catch (InvalidOperationException)
{
Logger.Warning("Seek before backend ready; ignoring");
} Prevention
- Only enable seek UI after the backend signals readiness
- Unsubscribe input/seek handlers in Dispose to avoid post-teardown seeks
- Track initialization state centrally so components query one source of truth
When it happens
Trigger: Calling Seek(TimeSpan) before the backend finished initialization (mediaSynchronizer still null), or after the backend was torn down and mediaSynchronizer.Stop()/release paths nulled it. Any code path that reaches Seek without a successful Initialize is affected.
Common situations: UI seek-bar handlers firing before video playback is ready; calling Seek on a video component whose Load failed earlier; seeking after Dispose due to a race between teardown and user input; platform where Initialize aborted early but the control is still interactive.
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
- The Media Codec Extractor has not been initialized
- Media is already open.
- Could not find asset {0} for bundle {1}
- Expect name1=value1;name2=value2 format.
- assetItem must be an absolute path
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/e76e718bd9143c69.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Video/Backends/MediaCodecVideoBackend.cs:173
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)
{
if (audioSoundInstance != null)
audioSoundInstance.Volume = volume;
foreach (var controller in audioControllers)
controller.Volume = volume;
}
public override void UpdatePlayRange() => mediaSynchronizer.PlayRange = Instance.PlayRange;
public override void UpdateLoopRange()
{
mediaSynchronizer.IsLooping = Instance.IsLooping;View on GitHub (pinned to 96fad776d2)