Yalantis/uCrop · error · CImgIOException

load_video(): File '%s', unable to locate frame %u.

Error message

load_video(): File '%s', unable to locate frame %u.

What it means

In the OpenCV-backed load_video(), after seeking/reading, if the resulting CImgList is still empty CImg concludes the requested first_frame could not be located in the video and throws this CImgIOException. Typically the frame index is beyond the last frame of the video, or the capture produced no frames at all.

Source

Thrown at ucrop/src/main/jni/CImg.h:67437

      }

      if (!go_on || (nb_frames && pos>=nb_frames)) { // Close video stream when necessary
        cimg::mutex(9);
        captures[index]->release();
        delete captures[index];
        captures[index] = 0;
        filenames[index].assign();
        positions[index] = 0;
        index = -1;
        cimg::mutex(9,0);
      }

      cimg::mutex(9);
      last_used_index = index;
      cimg::mutex(9,0);

      if (is_empty())
        throw CImgIOException(_cimglist_instance
                              "load_video(): File '%s', unable to locate frame %u.",
                              cimglist_instance,filename,first_frame);
      return *this;
#endif
    }

    //! Load an image from a video file, using OpenCV library \newinstance.
    static CImgList<T> get_load_video(const char *const filename,
                           const unsigned int first_frame=0, const unsigned int last_frame=~0U,
                           const unsigned int step_frame=1) {
      return CImgList<T>().load_video(filename,first_frame,last_frame,step_frame);
    }

    //! Load an image from a video file using the external tool 'ffmpeg'.
    /**
      \param filename Filename to read data from.
    **/
    CImgList<T>& load_ffmpeg_external(const char *const filename) {

View on GitHub (pinned to f788b534b4)

Solutions

  1. Query the video's frame count first (e.g. cv::VideoCapture CAP_PROP_FRAME_COUNT) and clamp first_frame/last_frame to it before calling load_video.
  2. Retry with first_frame=0 to confirm the file decodes at all; if it does, your index is out of range.
  3. For VFR videos, step frame-by-frame from 0 instead of seeking directly to a frame number.
  4. Re-encode the video to constant frame rate (ffmpeg -vsync cfr) to make seeking reliable.

Example fix

// before
list.load_video("clip.mp4", 9000); // clip has ~300 frames -> throws

// after
unsigned int first = std::min<unsigned int>(9000, getFrameCount("clip.mp4") - 1);
list.load_video("clip.mp4", first);
Defensive patterns

Strategy: validation

Validate before calling

// clamp frame index before loading
unsigned int total = probeFrameCount(file); // via cv::VideoCapture or ffprobe
if (firstFrame >= total) firstFrame = total > 0 ? total - 1 : 0;

Try / catch

try {
  list.load_video(file, first);
} catch (CImgIOException&) {
  list.load_video(file, 0); // fallback: first frame
}

Prevention

When it happens

Trigger: Calling load_video(filename, first_frame) where first_frame >= total frame count, or where the seek (CAP_PROP_POS_FRAMES) failed and no frames were grabbed.

Common situations: Hard-coded frame numbers used with user-supplied clips of varying length; videos whose frame count metadata is wrong, causing a seek past the end; variable-frame-rate videos where OpenCV seeking lands nowhere.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/03afbc33e9a1f7dd. Report an issue: GitHub.