Java实现视频截图和视频转码功能

之前一直想找一份可以实现Java操作视频文件的代码,找了很久,看到网上的都是很离散的一些功能实现,所以现在收集并整理了具体的功能实现,具体如下代码:

maven依赖:

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.5</version>
        </dependency>

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

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.5</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>4.0.1-1.4.4</version>
        </dependency>

        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>4.1-1.4.4</version>
        </dependency>

具体的实现工具类如下:

/**
 * @author zhq.xiang
 */
public class VedioUtils {
    /**
     * 截取视频的第一帧图片
     *
     * @param videoFile 可以用 inputStream 代替
     * @param outputStream
     */
    public static void fetchFrame(File videoFile, OutputStream outputStream, String outFormatName) {
        FFmpegFrameGrabber ff = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(videoFile);
            ff = new FFmpegFrameGrabber(fis);
            ff.start();
            int length = ff.getLengthInFrames();
            int i = 0;
            Frame frame = null;
            while (i < length) {
                // 过滤前5帧,避免出现全黑的图片,依自己情况而定
                frame = ff.grabFrame();
                if ((i > 5) && (frame.image != null)) {
                    break;
                }
                i++;
            }
            Java2DFrameConverter converter = new Java2DFrameConverter();
            BufferedImage bi = converter.getBufferedImage(frame);
            ImageIO.write(bi, outFormatName, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                if (ff != null) {
                    ff.stop();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 获取视频时长 单位/秒
     *
     * @param video 可以用inputStream代替
     * @return
     */
    public static long getVideoDuration(File video) {
        long duration = 0L;
        FFmpegFrameGrabber ff = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(video);
            ff = new FFmpegFrameGrabber(fis);
            ff.start();
            duration = ff.getLengthInTime() / (1000 * 1000);
            return duration;
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ff != null){
                try {
                    ff.stop();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return 0L;
    }


    /**
     * 转换视频文件为mp4
     *
     * @param file 可以用inputStream代替
     * @return
     */
    public static String convert2Mp4(File file) {
        FFmpegFrameGrabber frameGrabber = null;
        Frame capturedFrame = null;
        FFmpegFrameRecorder recorder = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            frameGrabber = new FFmpegFrameGrabber(fis);
            frameGrabber.start();
            String fileName = file.getAbsolutePath() + "__.mp4";
            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(),
                frameGrabber.getAudioChannels());
            //avcodec.AV_CODEC_ID_H264 清晰度较低 //AV_CODEC_ID_MPEG4 清晰度更高
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.setSampleRate(frameGrabber.getSampleRate());

            recorder.setAudioChannels(frameGrabber.getAudioChannels());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.start();
            while ((capturedFrame = frameGrabber.grabFrame()) != null) {
                recorder.setTimestamp(frameGrabber.getTimestamp());
                recorder.record(capturedFrame);
            }

            return fileName;
        } catch (Exception e) {
            e.printStackTrace();
        } catch (FrameRecorder.Exception e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(recorder != null) {
                try {
                    recorder.stop();
                    recorder.release();
                } catch (FrameRecorder.Exception e) {
                    e.printStackTrace();
                }
            }
            if(frameGrabber != null) {
                try {
                    frameGrabber.stop();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    public static void main(String[] args) {
        File file = new File("/Users/xiangzhongqiang/Downloads/hailuo_20783575_RF.mov");
        String destPath = "/Users/xiangzhongqiang/Downloads/1111.jpg";
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(destPath);
            fetchFrame(file, fos,
                destPath.substring(destPath.indexOf(Constants.SYMBOL_DOT)).replaceAll("\\" + Constants.SYMBOL_DOT, ""));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        convert2Mp4(file);

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章