zoukankan      html  css  js  c++  java
  • javacv FFmpeg 视频压缩

    package com.nmcc.demo.utils;
     
    import lombok.extern.slf4j.Slf4j;
    import org.bytedeco.javacpp.avcodec;
    import org.bytedeco.javacpp.avutil;
    import org.bytedeco.javacv.FFmpegFrameGrabber;
    import org.bytedeco.javacv.FFmpegFrameRecorder;
    import org.bytedeco.javacv.Frame;
     
    import java.io.File;
     
    /**
     * @author 
     * @date 2020/2/17
     * <p>
     * Description:
     */
    @Slf4j
    public class ConvertVideo {
     
        private static final int FRAME_RATE = 30;
        private static final int VIDEO_BITRATE = 1048576;
        private static final int COMPRESS_WIDTH = 320;
     
     
        /**
     * 在使用时发现视频压缩和视频时长有关系
     * 一个9M的56s的视频压缩后视频7M多
     * 一个22M的5s的视频压缩后视频624K
     * @param file
     * @param checkCompress
     * @return
     */
        public static String convert(File file, Boolean checkCompress) {
     
            FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file.getAbsolutePath());
            String fileName = null;
     
            Frame captured_frame = null;
     
            FFmpegFrameRecorder recorder = null;
     
            try {
                frameGrabber.start();
                fileName = file.getAbsolutePath().replace(".mp4", "_edited.mp4");
                log.info("wight:{},height:{}",frameGrabber.getImageWidth(), frameGrabber.getImageHeight());
     
                int height = frameGrabber.getImageHeight();
                int widht = frameGrabber.getImageWidth();
                if(checkCompress && needCompress(file.length())){
                    height = calculateHeight(frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), COMPRESS_WIDTH);
                    widht = COMPRESS_WIDTH;
                    log.info("new wight:{},height:{}",widht, height);
                }
                recorder = new FFmpegFrameRecorder(fileName, widht, height, frameGrabber.getAudioChannels());
                recorder.setFrameRate(FRAME_RATE);
                //下面这行打开就报错
                //recorder.setSampleFormat(frameGrabber.getSampleFormat());
                recorder.setSampleRate(frameGrabber.getSampleRate());
                //recorder.setAudioChannels(1);
                recorder.setVideoOption("preset", "veryfast");
                // yuv420p,像素
                recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
                recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
                recorder.setFormat("mp4");
                //比特
                //recorder.setVideoBitrate(VIDEO_BITRATE);
                recorder.start();
     
                while (true) {
                    try {
                        captured_frame = frameGrabber.grabFrame();
                        if (captured_frame == null) {
                            System.out.println("!!! end cvQueryFrame");
                            break;
                        }
                        recorder.setTimestamp(frameGrabber.getTimestamp());
                        recorder.record(captured_frame);
                        } catch (Exception e) {
                    }
                }
                recorder.stop();
                recorder.release();
                frameGrabber.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
            //file.delete();
            return fileName;
        }
     
        /**
         * 是否需要压缩,大于3MB
         * @param length
         * @return
         */
        public static boolean needCompress(long length){
            log.info("video size:{}", length);
            return length >= 3145728;
        }
     
        /**
         * 等比计算新高度
         * @param w
         * @param h
         * @param nw
         * @return
         */
        private static int calculateHeight(int w, int h, int nw){
            double s = Integer.valueOf(h).doubleValue() / Integer.valueOf(w).doubleValue();
            int height = (int) (nw * s);
            //如果宽和高不是偶数recorder.start();会报错
            if(height % 2 !=0){
                height += 1;
            }
            return height;
        }
    }

    引入压缩视频的java依赖

    <!--start视频截取相关-->
    <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.4.3</version>
    <exclusions>
    <exclusion>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacpp</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>flycapture</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>libdc1394</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>libfreenect</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>libfreenect2</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>librealsense</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>videoinput</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>opencv</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>tesseract</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>leptonica</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>flandmark</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>artoolkitplus</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.4.3</version>
    <exclusions>
    <exclusion>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>flycapture-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>libdc1394-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>libfreenect-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>libfreenect2-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>librealsense-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>videoinput-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>opencv-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>tesseract-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>leptonica-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>flandmark-platform</artifactId>
    </exclusion>
    <exclusion>
    <groupId>org.bytedeco.javacpp-presets</groupId>
    <artifactId>artoolkitplus-platform</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <!--视频截取相关end-->
  • 相关阅读:
    中国历史朝代公元对照简表
    [Solved] DashBoard – Excel Service: The data sources may be unreachable, may not be responding, or may have denied you access.
    Delete/Remove Project from TFS 2010
    Sharepoint site showing system account instead of my username on the top right corner.
    你的成功在于你每天养成的习惯
    Internet Information Services is running in 32bit emulation mode. Correct the issue listed above and rerun setup.
    Prepare to back up and restore a farm (Office SharePoint Server 2007)
    Word中字号与磅值的对应关系
    How to: Change the Frequency for Refreshing the Data Warehouse for Team System
    UI Automation in WPF/Silverlight
  • 原文地址:https://www.cnblogs.com/nmcc33/p/12325889.html
Copyright © 2011-2022 走看看