美文网首页Java基础
Java 获取视频时长及截取帧截图

Java 获取视频时长及截取帧截图

作者: ef6f9c30080a | 来源:发表于2019-08-17 09:33 被阅读125次

    前言

    只是最近碰到有这方面的项目需求,所以简单 Mark 下本文。下面的示例是参考过他人分享的文章,之后本人再自行实践、调整和测试过的,希望对有这方面需求的人有所帮助。

    示例

    1. 添加依赖
            <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacv-platform</artifactId>
                <version>1.4.4</version>
            </dependency>
    

    上述这段 maven 依赖包含了完整的 javacv 功能 (非常多,依赖Jar就占大概有500MB),由于这里只使用到了其中 ffmpeg 这块的特性,因此也可以像下面这样排除掉无关的部分

            <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacv</artifactId>
                <version>1.4.4</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.4</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>
    
    1. 核心代码
    • 获取视频时长
        /**
         * 获取视频时长,单位为秒
         *
         * @param video 源视频文件
         * @return 时长(s)
         */
        public static long getVideoDuration(File video) {
            long duration = 0L;
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);
            try {
                ff.start();
                duration = ff.getLengthInTime() / (1000 * 1000);
                ff.stop();
            } catch (FrameGrabber.Exception e) {
                e.printStackTrace();
            }
            return duration;
        }
    
    • 截取视频指定帧为图片
        /**
         * 截取视频获得指定帧的图片
         *
         * @param video   源视频文件
         * @param picPath 截图存放路径
         */
        public static void getVideoPic(File video, String picPath) {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);
            try {
                ff.start();
    
                // 截取中间帧图片(具体依实际情况而定)
                int i = 0;
                int length = ff.getLengthInFrames();
                int middleFrame = length / 2;
                Frame frame = null;
                while (i < length) {
                    frame = ff.grabFrame();
                    if ((i > middleFrame) && (frame.image != null)) {
                        break;
                    }
                    i++;
                }
    
                // 截取的帧图片
                Java2DFrameConverter converter = new Java2DFrameConverter();
                BufferedImage srcImage = converter.getBufferedImage(frame);
                int srcImageWidth = srcImage.getWidth();
                int srcImageHeight = srcImage.getHeight();
    
                // 对截图进行等比例缩放(缩略图)
                int width = 480;
                int height = (int) (((double) width / srcImageWidth) * srcImageHeight);
                BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
                thumbnailImage.getGraphics().drawImage(srcImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
    
                File picFile = new File(picPath);
                ImageIO.write(thumbnailImage, "jpg", picFile);
    
                ff.stop();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    1. 测试用例
        public static void main(String[] args) {
            String videoPath = ResourceUtils.CLASSPATH_URL_PREFIX + "video.mp4";
            File video = null;
            try {
                video = ResourceUtils.getFile(videoPath);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            String picPath = "video.jpg";
            getVideoPic(video, picPath);
    
            long duration = getVideoDuration(video);
            System.out.println("videoDuration = " + duration);
        }
    

    示例源码
    欢迎关注我的个人公众号:超级码里奥
    如果这对您有帮助,欢迎点赞和分享,转载请注明出处

    相关文章

      网友评论

        本文标题:Java 获取视频时长及截取帧截图

        本文链接:https://www.haomeiwen.com/subject/mrrurctx.html