java 音频、视频获取时长、截取封面、文件大小工具

依赖导入

<!-- 获取时长 -->
<dependency>
    <groupId>it.sauronsoftware</groupId>
    <artifactId>jave</artifactId>
    <version>1.0.2</version>
</dependency>
<!-- 截取封面(大小500MB左右,里面包含了多端的jar) -->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.4.4</version>
</dependency>
/**
 * 文件上传
 */
public R<String> uploadFile(MultipartFile file) throws Exception {
    String path = "./file/";
    File dir = new File(path);
    if (!dir.exists()) {
        dir.mkdir();
    }
    String originalFilename = file.getOriginalFilename();
    String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
    String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + suffix;
    File tmp = new File(path + fileName);
    FileOutputStream fileOutputStream = new FileOutputStream(tmp);
    IOUtils.copy(file.getInputStream(), fileOutputStream);
    Map<String, Object> map = new HashMap<>();
    map.put("size", FileSizeUtils.formatFileSize(file.getSize()));
    map.put("fileName", fileName);
    map = VideoUtils.fetchFrame(map, path, path + fileName, 1);
    return R.isOk().data(map);
}

## 方法一(通过jar方法截取图片和获取时长,长视频可能会失败)

/**
 * 获取指定视频的帧并保存为图片至指定目录
 * @param videofile  源视频文件路径
 * @param framefile  截取帧的图片存放路径
 * @throws Exception
 */
public static Map fetchFrame(Map map, String framefile, String videofile)
        throws Exception {
    String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
    File targetFile = new File(framefile+fileName);
    FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videofile);
    // 获取视频时长
    Encoder encoder = new Encoder();
    MultimediaInfo multimediaInfo = encoder.getInfo(new File(videofile));
    long ls = multimediaInfo.getDuration()/1000;
    int hour = (int) (ls/3600);
    int minute = (int) (ls%3600)/60;
    int second = (int) (ls-hour*3600-minute*60);
    log.info("视频时长为:{}时{}分{}秒", hour, minute, second);
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
    map.put("duration", simpleDateFormat.format(simpleDateFormat.parse(hour+":"+minute+":"+second)));
    frameGrabber.start();
    int lenght = frameGrabber.getLengthInFrames();
    int i = 0;
    Frame frame = null;
    while (i < lenght) {
        // 过滤前5帧,避免出现全黑的图片,依自己情况而定
        frame = frameGrabber.grabFrame();
        if ((i > 5) && (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, "png", picFile);
    map.put("cover", fileName);
    frameGrabber.stop();
    return map;
}

## 方法二(通过操作linux服务器获取图片和时长)

/**
 * 获取指定视频的帧并保存为图片至指定目录
 * @param videofile  源视频文件路径
 * @param framefile  截取帧的图片存放路径
 * @throws Exception
 */
public static Map fetchFrame(Map map, String framefile, String videofile, int type) throws Exception {
    String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
    //获取视频时长
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
    map.put("duration", simpleDateFormat.format(simpleDateFormat.parse( processInfoCmd(videofile, framefile+fileName, 2))));
    if (type == 1) {
        //截取封面图
        processInfoCmd(videofile, framefile+fileName, 1);
        map.put("cover", fileName);
    }
    return map;
}

/**
 * 通过linux指令获取封面和时长
 */
public static String processInfoCmd(String videoPath, String coverPath, int type) {
    String command = null;
    if (type == 1) {//截取图片
        command = "ffmpeg -ss 00:00:05 -i " + videoPath + " -f image2 -y " + coverPath;
    } else {//获取时长
        command = "ffmpeg -i "+videoPath+" -hide_banner 2>&1 | grep 'Duration' | cut -b 13-23";
    }
    String result = null;
    try {
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(command);
        InputStream stderr = proc.getErrorStream();
        InputStreamReader isr = new InputStreamReader(stderr);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        while ((line = br.readLine()) != null) {
            if (type != 1) {
                if (line.contains("Duration:")) {
                    int start = line.indexOf("Duration:");
                    int end = line.indexOf(", start:");
                    result = line.substring(start, end).substring("Duration:".length()).substring(0,9);
                    System.out.println(result.substring(0,9));
                }
            }
        }
        int exitVal = proc.waitFor();
        stderr.close();
        isr.close();
        br.close();
    } catch (Throwable t) {
        t.printStackTrace();
    }
    return result;
}

FileSizeUtils工具类来源于:https://www.cnblogs.com/zhukaixin/p/10691305.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值