FFMPEG Video conversion

596 Views Asked by At

Working on a project which requires conversion from video of quicktime to mp4 format Using the javacv maven library

 <dependency>
        <groupId>org.bytedeco</groupId>
        <artifactId>javacv-platform</artifactId>
        <version>1.5.8</version>
 </dependency>

Here is the code format using MPEG4 codec

 public static ByteArrayOutputStream convertToMp4(String videoId, byte[] file) {
        classLogger.trace("request is received to convert video: " + videoId + " to mp4");
        FFmpegLogCallback.set();
        InputStream stream = new ByteArrayInputStream(file);
        Frame captured_frame = null;
        FFmpegFrameRecorder recorder = null;
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(stream);
        SeekableByteArrayOutputStream outputStream = new SeekableByteArrayOutputStream();
        try {
            grabber.start();
            System.out.println("grabber frame rate " + grabber.getFrameRate()); //value is 29.85882710114861
            recorder = new FFmpegFrameRecorder(outputStream, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
            System.out.println("recorder frame rate b4 " + recorder.getFrameRate()); //value is 30.0
            recorder.setFormat("mp4");
            recorder.setFrameRate(grabber.getFrameRate());
            recorder.setAudioMetadata(grabber.getAudioMetadata());
            recorder.setAudioOption("crf", "0");
            recorder.setAudioQuality(0);
            recorder.setVideoBitrate(grabber.getVideoBitrate());
            recorder.setAudioBitrate(grabber.getAudioBitrate());
            recorder.setSampleRate(grabber.getSampleRate());
            recorder.setVideoMetadata(grabber.getVideoMetadata());
            recorder.start();
            while ((captured_frame = grabber.grabFrame()) != null) {
                try {
                    recorder.setTimestamp(grabber.getTimestamp());
                    recorder.record(captured_frame);
                } catch (Exception e) {
                    classLogger.error(e.getMessage());
                }
            }
            recorder.stop();
            recorder.release();
            grabber.stop();
            grabber.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return outputStream;
    }

The following code fails with the error

Error: [mpeg4 @ 0x7f61043a6e40] timebase 19763/590100 not supported by MPEG 4 standard, the maximum admitted value for the timebase denominator is 65535

org.bytedeco.javacv.FFmpegFrameRecorder$Exception: avcodec_open2() error -22: Could not open video codec. (For more details, make sure FFmpegLogCallback.set() has been called.)

I tried changing frame rate to alter the value of timebase but was of no help

I also tried changing the codec to H264 and here the video was converted successfully but there was a significant loss in frames and the video quality was distorted. Even though the video was converted successfully there was the following error log during the conversion

Error: [mp4 @ 0x7fc2486d9b80] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 2094878 >= 2094878
av_interleaved_write_frame() error -22 while writing interleaved video packet. (For more details, make sure FFmpegLogCallback.set() has been called.)

Any help will be highty appreciated, Thanks

0

There are 0 best solutions below