1

in the last time I had some struggle with the VideoWriter in openCV under java. I want to write a video file in a *.mp4 container with h.264 codec - but I see no option to toggle bitrate or quality in openCV VideoWriter. I did build openCV with ffmpeg as backend. I just want to write the video file in exact quality values as the original input video. I also have some code to do the job

import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.videoio.VideoWriter;
import org.opencv.videoio.Videoio;

public class VideoOutput
{
     private final int H264_CODEC = 33;

     private VideoWriter writer;

     private String filename;

     public VideoOutput (String filename)
     {
        writer = null;

        this.filename = filename;
    }

    public void initialize(double framesPerSecond, int height, int width) throws Exception
    {

        this.writer = new VideoWriter();

        this.writer.open(filename, H264_CODEC, framesPerSecond, new Size(width, height));

        if(!writer.isOpened())
        {
             Logging.LOGGER.severe("Could not create video output file " + filename + "\n");

             throw new Exception("Could not create video output file " + filename + "\n");
        }
    }

    public void setFrame(VideoFrame videoFrame) throws Exception
    {
         if (writer.isOpened()) 
         {
             Mat frame = ImageUtil.imageToMat(videoFrame.getFrame());

             writer.write(frame);

             frame.release();
         }
    }

I hoped the VideoWriter gives some options to do the job but it seems not the way.

So is there an option or flag that I am missing for lossless h264 video writing under openCV and java OR maybe there is another way to do this? Please help me - if you have done this already I really would appreciate some example code to get things done.

UPDATE

I do have now a solution that fits for my application, so here it is:

String fps = Double.toString(this.config.getInputConfig().getFramesPerSecond());

Runtime.getRuntime().exec(
        new String[] {
        "C:\\ffmpeg-3.4.2-win64-static\\bin\\ffmpeg.exe",
        "-framerate",
        fps,
        "-i",
        imageOutputPath + File.separator +  "%01d.jpg",
        "-c:v",
        "libx265",
        "-crf",
        "1",
        imageOutputPath + File.separator +  "ffmpeg.mp4"
        }
    );

Credits to @Gyan who gave me the correct ffmpeg call in this post:

Win/ffmpeg - How to generate a video from images under ffmpeg?

Greets

  • Believe it's not [possible](https://video.stackexchange.com/q/24179/1871). – Gyan Aug 14 '18 at 14:05
  • So it seems like openCV uses ffmpeg for h264 and ffmpeg is using openh264 from cisco to do the job right? So it would be neccessary to look into ffmpeg source change it the way that the quality/bitrate is dynamic and the change openCV interface to address those new functions in ffmpeg right? Is there any other option to do a quick job? – JohnDoeAnon Aug 14 '18 at 14:24
  • In python and with the scikit-video package it seems possible to configure the lossless mode: https://gist.github.com/docPhil99/a612c355cd31e69a0d3a6d2f87bfde8b – JohnDoeAnon Aug 14 '18 at 14:36
  • Or you can just use ffmpeg directly via a shell. – Gyan Aug 14 '18 at 14:38
  • Maybe you have java code to provide an example for calling ffmpeg in a loop with desired params with the shell? – JohnDoeAnon Aug 14 '18 at 14:41
  • @Gyan or maybe just the ffmpeg call, where I put an image into the call plus lossless option and outputfile - sorry I am not into this ffmpeg stuff – JohnDoeAnon Aug 14 '18 at 14:51

0 Answers0