java获取视频封面图片

目录

    • 代码
    • 结果

代码

解释:

  • 如果random是true,那么将按照coverNum来随机截取封面
  • 如果random是false,那么将按照coverNum来顺序截取封面,返回总封面数量不会超过视频总秒数

代码:

public class Test {
    public static void main(String[] args) {
        // 视频全路径,目前发现支持mp4、webm,其他的需要自己去尝试
        File videoFile = new File("C:\\download\\谷歌浏览器\\202207\\搞笑--一个字绝_爱给网_aigei_com.webm");
        // 封面数量
        long coverNum = 1;
        // 是否随机生成封面
        boolean random = false;
        Map<Long, String> coverMap = generateCover(videoFile, coverNum, random);
        coverMap.forEach((key, value) -> System.out.printf("截图秒数:%s秒;图片地址:%s\n", key, value));
    }

    /**
     * 生成视频封面
     * @author 明快de玄米61
     * @date   2022/12/4 16:34
     * @param  videoFile 视频全路径,目前发现支持mp4、webm,其他的需要自己去尝试
     * @param  coverNum 封面数量
     * @param  random 是否随机生成封面
     * @return map,其中key是秒数,而value是图片全路径
     **/
    private static Map<Long, String> generateCover(File videoFile, long coverNum, boolean random) {
        // 验证视频
        if (!(videoFile != null && videoFile.isFile() && videoFile.exists())) {
            throw new RuntimeException("参数:videoFile 不符合要求");
        }
        // 验证封面数量
        if (coverNum <= 0) {
            throw new RuntimeException("参数:coverNum 必须大于0");
        }

        // 存储封面
        Map<Long, String> coverMap = new TreeMap<>();

        // 生成封面
        FFmpegFrameGrabber grabber = null;
        try {
            // 初始化FFmpegFrameGrabber
            grabber = new FFmpegFrameGrabber(videoFile);
            grabber.start();

            // 获取截取秒数
            Set<Long> secondSet = generateSecondList(grabber, coverNum, random);

            // 循环生成封面
            for (Long second : secondSet) {
                // 设置封面截取时间
                grabber.setTimestamp(second * 1000000L);
                Frame f = grabber.grabImage();
                Java2DFrameConverter converter = new Java2DFrameConverter();
                BufferedImage bi = converter.getBufferedImage(f);

                // 指定封面保存地址
                File imgFile = createTempFile("cover.jpg");

                // 生成封面图片
                ImageIO.write(bi, "jpg", imgFile);

                // 装载封面图片
                coverMap.put(second, imgFile.getAbsolutePath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (grabber != null) {
                    grabber.stop();
                    grabber.release();
                }
            } catch (FFmpegFrameGrabber.Exception e) {
                e.printStackTrace();
            }
        }

        return coverMap;
    }

    /**
     * 获取封面截图秒数集合
     * @author 明快de玄米61
     * @date   2022/12/4 17:51
     * @param  grabber FFmpegFrameGrabber对象
     * @param  coverNum 封面数量
     * @param  random 是否随机生成封面
     * @return 封面截图秒数集合
     **/
    @SneakyThrows
    private static Set<Long> generateSecondList(FFmpegFrameGrabber grabber, long coverNum, boolean random) {
        // 存储封面截图秒数集合
        Set<Long> secondSet = new TreeSet<>();

        // 获取视频时长秒数;说明:除以1000000可以获取秒数
        long totalVideoSecond = grabber.getLengthInTime() / 1000000;

        // 随机生成截图时间
        if (random)
        {
            Random secureRandom = SecureRandom.getInstanceStrong();
            for (int i = 1; i <= coverNum; i++) {
                secondSet.add((long) (secureRandom.nextInt((int) totalVideoSecond - 1) + 1));
            }
        }
        // 自定义截图时间
        else
        {
            coverNum = totalVideoSecond > coverNum ? coverNum : totalVideoSecond;
            for (long i = 1; i <= coverNum; i++) {
                secondSet.add(i);
            }
        }

        return secondSet;
    }

    /**
     * 生成临时文件
     * @author 明快de玄米61
     * @date   2022/12/4 18:00
     * @param  fileName 文件全名称
     * @return file文件
     **/
    public static File createTempFile(String fileName) {
        try {
            // 参数判断
            if (StringUtils.isBlank(fileName) || fileName.lastIndexOf(".") < 0) {
                return null;
            }
            // 创建临时目录
            String tmpdirPath = System.getProperty("java.io.tmpdir");
            String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String uuId = UUID.randomUUID().toString().replaceAll("-", "");
            String[] params = {tmpdirPath, dateStr, uuId};
            // 结果例如:C:\Users\Administrator\AppData\Local\Temp\20220630\0f774122c38b423793cc1c121611c142
            String fileUrl = StringUtils.join( params, File.separator);
            if (!new File(fileUrl).exists()) {
                new File(fileUrl).mkdirs();
            }
            // 创建临时文件
            File file = new File(fileUrl, fileName);
            file.createNewFile();
            return file;
        } catch (Exception e) {
            System.out.println("》》》创建临时文件失败,临时文件名称:" + fileName);
            e.printStackTrace();
        }
        return null;
    }
}

结果

截图秒数:1秒;图片地址:C:\Users\mingming\AppData\Local\Temp\20221204\9ce19ca9932947399bf17d9e0facd037\cover.jpg

你可能感兴趣的:(java学习之路,java,开发语言)