Java获取视频封面图,利用FFmpegFrameGrabber获取视频封面图

依赖

xml 复制代码
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.9</version>
        </dependency>

传入视频流获取图片byte

java 复制代码
    /**
     * 获取视频截图
     *
     * @param frameNumber 视频的指定帧数
     * @param vName       视频名称
     * @param videoBytes  视频字节
     * @return 图片byte数组
     */
    private byte[] getCoverImageBytes(Integer frameNumber, String vName, byte[] videoBytes) {
        Double videoSize = DoubleUtil.getDouble2(videoBytes.length / 1024.0 / 1024.0);
        long timeMillis = System.currentTimeMillis();
        logger.info("截取视频截图开始 视频名称:{} 视频大小:{}MB", vName, videoSize);
        try (ByteArrayInputStream is = new ByteArrayInputStream(videoBytes);
             FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(is);
             ByteArrayOutputStream os = new ByteArrayOutputStream();
             Java2DFrameConverter converter = new Java2DFrameConverter()) {
            grabber.start();
            //视频的最大帧数,减少10帧是因为最后几帧会出现获取不到图片的情况
            int ftp = grabber.getLengthInFrames() - 10;
            frameNumber = ftp < frameNumber ? ftp : frameNumber;
            //设置视频指定帧数
            grabber.setFrameNumber(frameNumber);
            //设置视频截取帧(默认取第一帧)
            Frame frame = grabber.grabImage();
            //绘制图片
            BufferedImage bi = converter.getBufferedImage(frame);
            ImageIO.write(bi, "jpg", os);
            grabber.stop();
            logger.info("截取视频截图结束,处理时间: {}秒", (System.currentTimeMillis() - timeMillis) / 1000);
            return os.toByteArray();
        } catch (FrameGrabber.Exception e) {
            logger.error("FrameGrabber.Exception :{}", e.getMessage());
        } catch (IOException e) {
            logger.error("IOException :{}", e.getMessage());
        }
        logger.info("获取视频封面图失败 vName:{}", vName);
        return null;
    }

传入视频流获取图片文件

java 复制代码
/**
     * 传入视频文件,生成对应的封面图文件
     *
     * @param frameNumber 帧数
     * @param file        视频文件
     */
    private void coverImage(Integer frameNumber, File file) {
        String vName = file.getName();
        Double videoSize = DoubleUtil.getDouble2(file.length() / 1024.0 / 1024.0);
        long timeMillis = System.currentTimeMillis();
        logger.info("截取视频截图开始 视频名称:{} 视频大小:{}MB", vName, videoSize);
        try (FileInputStream is = new FileInputStream(file);
             FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(is);
             Java2DFrameConverter converter = new Java2DFrameConverter()) {
            grabber.start();
            //视频的最大帧数,减少10帧是因为最后几帧会出现获取不到图片的情况
            int ftp = grabber.getLengthInFrames() - 10;
            frameNumber = ftp < frameNumber ? ftp : frameNumber;
            //设置视频指定帧数
            grabber.setFrameNumber(frameNumber);
            // 图片名称
            String targetFileName = vName.substring(0, vName.lastIndexOf(".")) + "_vc.jpg";
            logger.info("图片名称:{}", targetFileName);
            File imageFile = new File("D:\\my_work\\" + targetFileName);
            //设置视频截取帧(默认取第一帧)
            Frame frame = grabber.grabImage();
            //绘制图片
            BufferedImage bi = converter.getBufferedImage(frame);
            ImageIO.write(bi, "jpg", imageFile);
            grabber.stop();
            logger.info("截取视频截图结束,处理时间: {}秒", (System.currentTimeMillis() - timeMillis) / 1000);
        } catch (FrameGrabber.Exception e) {
            logger.error("FrameGrabber.Exception :{}", e.getMessage());
        } catch (IOException e) {
            logger.error("IOException :{}", e.getMessage());
        }
相关推荐
特立独行的猫A15 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
budingxiaomoli1 天前
Spring统一功能处理
java·后端·spring
Flynn Liang1 天前
可观测性与成本治理:一次对话的 17 个观测点
java·langchain·可观测性·micrometer·langchain4j·token 成本·llm 监控
金銀銅鐵1 天前
带您看懂字节码指令(三):同一行加法,为什么有四种指令
java·jvm
2301_790355971 天前
【技术拆解】短视频配音自动化流程:从文案预处理到 SRT 字幕的 9 个环节
自然语言处理·音视频
文丑颜不良啊1 天前
LeetCode2821~2840题目解析
java·leetcode
apcipot_rain1 天前
C++转Java日记(10)
java·开发语言
简 洁 冬冬1 天前
泛型方法写法全面辨析:从「能编译」到「能跑」到「能用」
java·泛型
LGL6030A1 天前
Java学习历程31——初识Spring Boot
java·spring boot·学习
Lansonli1 天前
大数据Spark(八十八):Spark任务资源之Standalone集群测试
java·服务器·spark