Yalantis/uCrop · warning

save_video(): Cannot output streamed video, as this requires

Error message

save_video(): Cannot output streamed video, as this requires features from the OpenCV library ('-Dcimg_use_opencv') must be defined).

What it means

CImgList<T>::save_video() with keep_open=true requires OpenCV streaming features. In builds without cimg_use_opencv, the call warns that streamed (kept-open) video output is unavailable, then falls back to saving via an external ffmpeg process for the non-empty case.

Source

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

          _data[l].save_gzip_external(nfilename);
        }
      }
      return *this;
    }

    //! Save image sequence (using the OpenCV library when available).
    /**
       \param filename Filename to write data to.
       \param fps Number of frames per second.
       \param codec Type of compression (See http://www.fourcc.org/codecs.php to see available codecs).
       \param keep_open Tells if the video writer associated to the specified filename
       must be kept open or not (to allow frames to be added in the same file afterwards).
    **/
    const CImgList<T>& save_video(const char *const filename, const unsigned int fps=25,
                                  const char *codec=0, const bool keep_open=false) const {
#ifndef cimg_use_opencv
      cimg::unused(codec,keep_open);
      if (keep_open) cimg::warn(_cimglist_instance
                                "save_video(): Cannot output streamed video, as this requires features from the "
                                "OpenCV library ('-Dcimg_use_opencv') must be defined).",
                                cimglist_instance);
      if (!is_empty()) return save_ffmpeg_external(filename,fps);
      return *this;
#else
      try {
        static cv::VideoWriter *writers[32] = {};
        static CImgList<charT> filenames(32);
        static CImg<intT> sizes(32,2,1,1,0);
        static int last_used_index = -1;

        // Detect if a video writer already exists for the specified filename.
        cimg::mutex(9);
        int index = -1;
        if (filename) {
          if (last_used_index>=0 && !std::strcmp(filename,filenames[last_used_index])) {
            index = last_used_index;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Rebuild with cimg_use_opencv defined and link OpenCV (imgcodecs/videoio) to enable streamed output
  2. Set keep_open=false and save the complete list in one call (still uses external ffmpeg)
  3. Ensure the external ffmpeg binary is on PATH since the fallback path shells out to it
  4. Restructure code to accumulate frames and write once at the end

Example fix

// before
frames.save_video("out.mp4", 30, nullptr, true); // warns, streaming unsupported
// after
#ifdef cimg_use_opencv
frames.save_video("out.mp4", 30, nullptr, true);
#else
frames.save_video("out.mp4", 30, nullptr, false); // one-shot external ffmpeg
#endif
Defensive patterns

Strategy: fallback

Validate before calling

#ifdef cimg_use_opencv
frames.save_video("out.mp4", fps, nullptr, true);
#else
if (std::system("command -v ffmpeg >/dev/null") == 0)
  frames.save_video("out.mp4", fps, nullptr, false);
#endif

Prevention

When it happens

Trigger: Calling save_video(filename, fps, codec, keep_open=true) on a build compiled without cimg_use_opencv; the warning fires only when keep_open is true, otherwise it silently saves via ffmpeg_external.

Common situations: Expecting incremental/streamed video writing (e.g. appending frames over time) on a plain CImg+ffmpeg build; CI or Android NDK builds where OpenCV was not linked; copying code that was written against an OpenCV-enabled CImg build.

Related errors


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