Yalantis/uCrop · error · CImgIOException

load_ffmpeg_external(): Failed to open file

Error message

load_ffmpeg_external(): Failed to open file '%s' with external command 'ffmpeg'.

What it means

load_ffmpeg_external() builds a command line invoking the external ffmpeg binary to decode the video into temporary PPM images. If cimg::system() returns non-zero (ffmpeg missing or it failed to open/decode the input), CImg throws this CImgIOException. It indicates the external ffmpeg invocation failed, not necessarily that the file is absent (that check happened earlier).

Solutions

  1. Install ffmpeg or set cimg::ffmpeg_path() to the correct binary location before calling load_video/load_ffmpeg_external.
  2. Run the same ffmpeg command manually on the file to see the real decode error (codec, permissions, corruption).
  3. Re-encode the video with ffmpeg to H.264/MP4, or use the OpenCV backend (cimg_use_opencv) instead.
  4. Verify ffmpeg_path is executable (check version output) from the same process/user context.

Example fix

// before
cimg::ffmpeg_path("/usr/local/bin/ffmpeg"); // binary absent in container
list.load_ffmpeg_external("clip.mp4");

// after
if (cimg::system(CImg<char>::string(cimg::ffmpeg_path()) + " -version") == 0) {
  list.load_ffmpeg_external("clip.mp4");
} else {
  // fall back: re-encode elsewhere or use OpenCV-backed load_video
}
Defensive patterns

Strategy: fallback

Validate before calling

// ensure ffmpeg is present and runnable before attempting load
bool ffmpegAvailable() {
  return cimg::system(
    CImg<char>::string(cimg::ffmpeg_path()) + " -version") == 0;
}

Try / catch

if (!ffmpegAvailable()) { /* use OpenCV backend or fail fast */ }
try {
  list.load_ffmpeg_external(file);
} catch (CImgIOException&) {
  list.load_video(file); // OpenCV backend fallback
}

Prevention

When it happens

Trigger: cimg::ffmpeg_path() points to a non-existent or non-executable ffmpeg; ffmpeg exits with error because the codec/container is unsupported or the file is corrupt; quoting/escaping issues with exotic filenames.

Common situations: Docker/CI images without ffmpeg installed; ffmpeg version too old for the video codec; PATH set differently inside the app (Android) than in the shell.

Related errors


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

Appendix: source

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

    **/
    CImgList<T>& load_ffmpeg_external(const char *const filename) {
      if (!filename || !cimg::is_file(filename))
        throw CImgArgumentException(_cimglist_instance
                                    "load_ffmpeg_external(): Specified filename is (null) or does not exist.",
                                    cimglist_instance);
      CImg<charT> command(1024), filename_tmp(256), filename_tmp2(256);
      do {
        cimg_snprintf(filename_tmp,filename_tmp._width,"%s%c%s",
                      cimg::temporary_path(),cimg_file_separator,cimg::filenamerand());
        cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_000001.ppm",filename_tmp._data);
      } while (cimg::path_exists(filename_tmp2));
      cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%%6d.ppm",filename_tmp._data);
      cimg_snprintf(command,command._width,"\"%s\" -v -8 -i \"%s\" \"%s\"",
                    cimg::ffmpeg_path(),
                    CImg<charT>::string(filename)._system_strescape().data(),
                    CImg<charT>::string(filename_tmp2)._system_strescape().data());
      if (cimg::system(command,cimg::ffmpeg_path())!=0)
        throw CImgIOException(_cimglist_instance
                              "load_ffmpeg_external(): Failed to open file '%s' with external command 'ffmpeg'.",
                              cimglist_instance,
                              filename);
      const unsigned int omode = cimg::exception_mode();
      cimg::exception_mode(0);
      assign();
      unsigned int i = 1;
      for (bool stop_flag = false; !stop_flag; ++i) {
        cimg_snprintf(filename_tmp2,filename_tmp2._width,"%s_%.6u.ppm",filename_tmp._data,i);
        CImg<T> img;
        try { img.load_pnm(filename_tmp2); }
        catch (CImgException&) { stop_flag = true; }
        if (img) { img.move_to(*this); std::remove(filename_tmp2); }
      }
      cimg::exception_mode(omode);
      if (is_empty())
        throw CImgIOException(_cimglist_instance
                              "load_ffmpeg_external(): Failed to open file '%s' with external command 'ffmpeg'.",

View on GitHub (pinned to f788b534b4)