stride3d/stride · error · InvalidOperationException

The Media Codec has not been initialized for a media

Error message

The Media Codec has not been initialized for a media

What it means

Thrown by MediaCodecExtractorBase.ExtractMedia when the worker thread starts pulling samples from the MediaCodec decoder before Initialize(media) was successfully called (or it was disposed/reset). The extractor guards two preconditions: MediaDecoder created, and isInitialized set for a specific media; this error fires for the second one, meaning the codec exists but was never configured for the current media source.

Solutions

  1. Call Extractor.Initialize(media) (and wait for its success) before starting extraction
  2. Check the return/exception of Initialize before starting the worker thread
  3. Re-create or re-initialize the extractor after Reset/Dispose before reuse
  4. Inspect thread startup ordering so ExtractMediaWorkerFunction cannot run before initialization completes

Example fix

// before
extractor.Reset();
extractor.ExtractMediaWorkerFunction(); // throws: not initialized for new media
// after
extractor.Reset();
extractor.Initialize(newMedia);
extractor.ExtractMediaWorkerFunction();
Defensive patterns

Strategy: validation

Validate before calling

if (extractor == null || !extractor.IsInitialized)
    throw new InvalidOperationException("Extractor must be initialized before extraction starts");

Type guard

bool IsReadyForExtraction(MediaCodecExtractorBase e) => e is { MediaDecoder: not null } && e.IsInitialized;

Try / catch

try { extractor.ExtractMediaWorkerFunction(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("has not been initialized"))
{ /* re-initialize extractor and retry once */ }

Prevention

When it happens

Trigger: Calling ExtractMedia / starting the extraction worker without a prior successful Initialize() call for the media; calling Reset/Dispose and re-running extraction without re-initializing; a failed Initialize that left MediaDecoder non-null but isInitialized false.

Common situations: Reusing one extractor instance across multiple video files without re-initializing; races where the extraction thread starts before initialization completes; swallowing an exception from Initialize and continuing to play.

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/017f8d51888ed52e. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs:289

            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                Logger.Debug("Media Extraction done");
                Release();
            }
        }

        private void ExtractMedia()
        {
            if (MediaDecoder == null)
                throw new InvalidOperationException("The Media Codec Extractor has not been initialized");

            if (!isInitialized)
                throw new InvalidOperationException("The Media Codec has not been initialized for a media");
            
            var bufferInfo = new MediaCodec.BufferInfo();
            var waitDefaultTime = TimeSpan.FromMilliseconds(10);

            MediaDecoder.Start();
            while (true)
            {
                var waitTime = waitDefaultTime; // time to wait at the end of the loop iteration

                //Process the commands
                if (ProcessCommandsAndUpdateCurrentState())
                    waitTime = TimeSpan.Zero;

                // terminate the thread on disposal
                if (currentState == SchedulerAsyncCommandEnum.Dispose)
                    return;

                //=================================================================================================

View on GitHub (pinned to 96fad776d2)