stride3d/stride · error · InvalidOperationException
Media isn't open.
Error message
Media isn't open.
What it means
ExtractFrames extracts raw frames from an already-opened media. This InvalidOperationException is thrown when ExtractFrames is called on an FFmpegMedia whose Open() has not succeeded (IsOpen is false), or after the media was disposed.
Solutions
- Call Open(url) and confirm it succeeds before calling ExtractFrames
- Check the IsOpen property before extraction and open on demand
- Avoid using FFmpegMedia after Dispose; create a new instance
- Fix the root cause if Open previously failed (file path, codecs, memory)
Example fix
// before
media.ExtractFrames(stream, time => ...);
// after
if (!media.IsOpen) media.Open(url);
if (media.IsOpen)
media.ExtractFrames(stream, time => ...); Defensive patterns
Strategy: type-guard
Validate before calling
if (media.IsDisposed) throw new ObjectDisposedException(nameof(FFmpegMedia)); if (!media.IsOpen) media.Open(url);
Type guard
bool CanExtract(FFmpegMedia m) => !m.IsDisposed && m.IsOpen;
Try / catch
try { media.ExtractFrames(stream, cb); }
catch (InvalidOperationException ex) when (ex.Message == "Media isn't open.")
{
media.Open(url);
media.ExtractFrames(stream, cb);
} Prevention
- Always call Open before ExtractFrames
- Track media lifetime; never reuse disposed instances
- Check IsOpen property as a guard clause
When it happens
Trigger: Calling ExtractFrames(stream,...) before calling Open(url), after Open threw (leaving the media not open), or after Dispose().
Common situations: Calling extraction APIs in the wrong order in editor/tools code; Open failed earlier due to a missing or corrupt file and the error was swallowed; using the media object after disposal.
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
- Could not fill codec parameters. Error code=
- Could not initialize the conversion context.
- Couldn't allocate a frame for decoding.
- Couldn't allocate a frame for hardware decoding.
- Couldn't transfer frame data from GPU to CPU
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/98998fd26748518e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Video/FFmpeg/FFmpegMedia.cs:204
if (ret < 0)
{
Logger.Error($"Could not seek frame. Error code={ret.ToString("X8")}");
Logger.Error(GetErrorMessage(ret));
return false;
}
return true;
}
[ItemNotNull, NotNull]
public int ExtractFrames([NotNull] FFmpegStream stream, int count)
{
FFmpegUtils.EnsurePlatformSupport();
if (isDisposed)
throw new ObjectDisposedException(nameof(FFmpegMedia));
if (!IsOpen)
// TODO: log?
throw new InvalidOperationException(@"Media isn't open.");
var pCodecpar = stream.AVStream->codecpar;
var streamInfo = GetStreamInfo(stream);
var dstData = new byte_ptrArray4();
var dstLinesize = new int_array4();
ffmpeg.av_image_fill_arrays(ref dstData, ref dstLinesize, (byte*)streamInfo.Image.Buffer, DestinationPixelFormat, pCodecpar->width, pCodecpar->height, 1);
streamInfo.Image.Linesize = dstLinesize[0];
var extractedFrameCount = 0;
// FFmpeg 6.0+: av_init_packet removed; packets must be heap-allocated via av_packet_alloc.
var pPacket = ffmpeg.av_packet_alloc();
try
{
for (int i = 0; i < count; i++)
{
var extractionStatus = ExtractNextImage(streamInfo, pPacket, stream.AVStream, dstData, dstLinesize);View on GitHub (pinned to 96fad776d2)