Javacv: How to Crop a Video? (Question)

Created on 8 Dec 2017  路  11Comments  路  Source: bytedeco/javacv

Hi there,

I have a video (sample.mov) that contains 30secs of audio + video.
Now, imagine that the 5secs in the beginning and end of the video is just noise.

How can I crop the video starting at 5secs and ending on 25secs?
Generating then a new video file with only 20secs.

Should I use "FFmpegFrameGrabber" to grab the frames and send to a "FFmpegFrameRecorder"?
Is this the right approach? Any code samples would be greatly appreciated, thanks!

Also, thanks for the project. 馃憤

duplicate question

All 11 comments

Yes, that sounds like the right approach. Depending on the original video, you might not need to reencode the frames: https://github.com/bytedeco/javacv/issues/818#issuecomment-349094435

Thank you very much for your help! 馃専

Solution below - pretty straightforward:

            // long fiveSecs = 5000000;
            // long twentyFiveSecs = fiveSecs*5;
            // String sourceFile = "/tmp/VIDEO.MOV";
            // String outputFile = "/tmp/CROPPED_VIDEO.MOV";


    public void cropVideo(String sourceFile, String outputFile, long startTime, long endTime){
        try {

            FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(sourceFile);
            frameGrabber.start();

            int width = frameGrabber.getImageWidth();
            int height = frameGrabber.getImageHeight();
            int channels = frameGrabber.getAudioChannels();

            FFmpegFrameRecorder frameRecorder = new FFmpegFrameRecorder(outputFile, width, height, channels);
            frameRecorder.setAudioBitrate(frameGrabber.getAudioBitrate());
            frameRecorder.setVideoBitrate(frameGrabber.getVideoBitrate());
            frameRecorder.setVideoQuality(0); // MAX Quality!

            while (true) {
                Frame frame = frameGrabber.grab();
                if (frame != null){
                    Long timestamp = frameGrabber.getTimestamp();
                    if (timestamp < startTime) {
                        continue;
                    }
                    frameRecorder.record(frame);
                    if (timestamp > endTime) {
                        break;
                    }
                } else {
                    break;
                }
            }

            frameRecorder.stop();
            frameGrabber.stop();
        } catch (Exception ex) {
            throw new IllegalArgumentException("cropVideo :: could not crop video: "+sourceFile+" / "+outputFile+" / "+startTime+" / "+endTime, ex);
        }
    }

Hey @saudet

Quick question, how do I copy all metadata from "sourceFile" onto "outputFile" ?
Thank you very much for your help so far, really appreciate it 馃槃

Cheers 馃憤

Great! As for the metadata, I guess we would have to enhance FFmpegFrameGrabber and FFmpegFrameRecorder a bit for this. Could you send a pull request? :)

Thanks for the quick answer; as soon as I get some things out of the way I will try to contribute with a PR by adding this feature; cheers!

I've given access to the Map fields in the commit above. We can now do something like recorder.setMetadata(grabber.getMetadata()) and it should work!

That's great news!

Thanks for doing that, looking forward to the next release! 馃憤

Please try the SNAPSHOT artifacts!

Will do! If you don't hear back from me anymore is because all is going well.. 馃槅

Was this page helpful?
0 / 5 - 0 ratings

Related issues

y4nnick picture y4nnick  路  3Comments

newstarbka picture newstarbka  路  5Comments

eldhosengeorge picture eldhosengeorge  路  3Comments

myScoopAndroidCamera picture myScoopAndroidCamera  路  4Comments

fif10 picture fif10  路  3Comments