Merge two videos in Java , video fade in from right side and fade out to left

    Two videos , one video fade out from right to left side , the other video fade in from right to left.

 We can use JavaCV FFmpeg package to create such video effective.

The steps:

1.Load two video , video one and video two

2.Get the video information like frame rate , frame number,duration

3.Get the start frame number that start to fade out/in for both videos

4.Get the end frame number that fade out/in complete for both videos

5.Merge above two frames with corresponding gradient

The code:

public void mergeVideo()
    String videoOne = "video-1.mp4"
    String videoTwo = "video-2.mp4"
    String mergedVideo="mergedVideo.mp4";
    try {
        //load video one
        FFmpegFrameGrabber grabberOne = FFmpegFrameGrabber.createDefault(videoOne);
        //load video two
        FFmpegFrameGrabber grabberTwo = FFmpegFrameGrabber.createDefault(videoTwo);
        //get the width and height for merged video
        int maxWidth=grabberOne.getImageWidth()>grabberTwo.getImageWidth()?grabberOne.getImageWidth():grabberTwo.getImageWidth();
        int maxHeight=grabberOne.getImageHeight()>grabberTwo.getImageHeight()?grabberOne.getImageHeight():grabberTwo.getImageHeight();
        //create merged video
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(mergedVideo, maxWidth,
        //get amount of frame 
        int totalOne =grabberOne.getLengthInFrames();
        double frameRateOne=grabberOne.getFrameRate();
        int totalTwo=grabberTwo.getLengthInFrames();
        double frameRateTwo=grabberTwo.getFrameRate();
        //get duration in seconds
        long durationInSec = grabberOne.getFormatContext().duration() / 1000000;
        long durationTwoInSec = grabberTwo.getFormatContext().duration() / 1000000;
        //get start frame number for video one fade out
        int startFrameNum = getStartOrEndFrameNumber(3, durationInSec, totalOne);
        int endFrameNum = getStartOrEndFrameNumber(8, durationInSec, totalOne);
        //get start framte number for video two fade in 
        int grabeTwoEndFrameNum =getStartOrEndFrameNumber(5, durationTwoInSec, totalTwo);"1st duration {}",durationInSec);"1st total {}",totalOne);"1st frameRate {}",frameRateOne);"1st start frame num {}",startFrameNum);"1st end frame num {}",endFrameNum);"2nd duration {}",durationTwoInSec);"2nd total {}",totalTwo);"2nd frameRate {}",frameRateTwo);"2nd end frame num {}",grabeTwoEndFrameNum);"Uniform width {}, height {}",maxWidth,maxHeight);
        int i=0;
        double progress;
        Frame fTwo,fOne;
        Mat fadeInMat,fadeOutMat,resizedMat;
        OpenCVFrameConverter.ToMat conveter = new OpenCVFrameConverter.ToMat();
        DecimalFormat df = new DecimalFormat("#.00");
        while (i<=totalTwo) {
            // record video one frame 
            if (i <= startFrameNum) {
            fOne = grabberOne.grabImage();
          // video one fade out , video two fade in 
            else if (i > startFrameNum && i < endFrameNum) {
            resizedMat=new Mat();
            fOne = grabberOne.grabImage();
            fTwo = grabberTwo.grabImage();
            //resize frame
            resize(conveter.convertToMat(fOne), resizedMat, new Size(maxWidth, maxHeight));
            fadeOutMat = resizedMat;
            fadeInMat = conveter.convertToMat(fTwo);
            //calculate the picture weight
            progress = (i - startFrameNum) / (double) (endFrameNum - startFrameNum);
            //merge two frame and record it
            recorder.record(mergePhotoToFrame(fadeOutMat, fadeInMat, Double.valueOf(df.format(progress))));
            } else {
                fTwo = grabberTwo.grabImage();
                if (fTwo == null)
    } catch (Exception e) {
        LOGGER.error("", e);

public static int getStartOrEndFrameNumber(long startOrEndAtSecond, long durationInSecond, int totalFrame) {
    if (startOrEndAtSecond >= durationInSecond)
        return (int) durationInSecond;
    double percent = startOrEndAtSecond / (double) durationInSecond;
    return (int) Math.round(totalFrame * percent);

public static Frame mergePhotoToFrame(Mat srcFadeOut,Mat srcFadeIn,double progress)
    OpenCVFrameConverter.ToMat conveter = new OpenCVFrameConverter.ToMat();
    return conveter.convert(mergePhoto(srcFadeOut,srcFadeIn,progress));

public static Mat mergePhoto(Mat srcFadeOut,Mat srcFadeIn,double progress)
    if(progress <0||progress>1)
        return null;
    double srcAlpha=1-progress;
    Mat dest=new Mat();
    opencv_core.addWeighted(srcFadeOut,srcAlpha , srcFadeIn,progress, 0.0, dest);
    return dest;