记录一次判断视频时长

    技术2023-07-23  97

    做的是一个交友软件,用户可以上传个人小视频,需求是上传十秒以内的小视频,直接上代码:

    <dependency> <groupId>ws.schild</groupId> <artifactId>jave-all-deps</artifactId> <version>2.4.0</version> </dependency> <!--视频工具类 FFmpegFrameGrabber--> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>0.8</version> </dependency>

    上面是用到的依赖

    public static String uploadOriginalImage(String model, MultipartFile thumbnail) { if (!thumbnail.isEmpty() && thumbnail.getSize() != 0) { String realpath = Global.getWebUploadPath + File.separator + "thumbnail" + File.separator + model; String path = Global.getWebURl; String filename = thumbnail.getOriginalFilename(); // 获取文件后缀名 String suffixName = filename.substring(filename.lastIndexOf(".")); String newFileName = UUIDHexGenerator.getUUID32() + suffixName; try { FileIOUtils.writeFile(thumbnail.getBytes(), realpath + File.separator + newFileName); } catch (IOException e) { e.printStackTrace(); } return path + "/thumbnail/" + model + "/" + newFileName; } return ""; }

    上面是用到的工具类中的方法,主要将视频存入本地磁盘

    /** * 获取指定视频的帧并保存为图片至指定目录 * * @param videofile 源视频文件路径 * @param framefile 截取帧的图片存放路径 * @throws Exception */ public static Object fetchFrame(String videofile, String framefile) { try { //判断当前存储的路径是否存在 File dir = new File(framefile.substring(0, framefile.lastIndexOf("/"))); if (!dir.exists()) { dir.mkdirs(); } File targetFile = new File(framefile); FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile); ff.start(); int lenght = ff.getLengthInFrames(); int i = 0; Frame f = null; while (i < lenght) { // 过滤前5帧,避免出现全黑的图片,依自己情况而定 f = ff.grabFrame(); if ((i > 5) && (f.image != null)) { break; } i++; } IplImage img = f.image; int owidth = img.width(); int oheight = img.height(); // 对截取的帧进行等比例缩放 int width = 800; int height = (int) (((double) width / owidth) * oheight); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null); ImageIO.write(bi, "jpg", targetFile); ff.stop(); return null; } catch (Exception e) { log.error(e.getMessage()); throw new RuntimeException("截取视频出现错误:" + e.getMessage()); } }

    以上代码主要是截取视频中的某一帧作为视频的封面图

    /** * 判断小视频 如果大于10秒则返回 否则存入视频 存入其中一帧座位缩略图 * * @param multipartFile * @param user * @return 0代表视频超长 1代表上传成功 2代表上传出错 */ private Integer saveVideo(MultipartFile multipartFile, User user) throws Exception { //将视频存入 String videoPath = ImageUtil.uploadOriginalImage("user", multipartFile); String newFileName = videoPath.substring(0, videoPath.lastIndexOf("/")) + "/compress/" + System.currentTimeMillis() + ".jpg"; //这里是视频的存放路径 String realVideoPath = videoPath.replace("/file", Global.getWebUploadPath + File.separator); File file = new File(realVideoPath); //工具类 MultimediaObject instance = new MultimediaObject(file); MultimediaInfo result = instance.getInfo(); //获取视频时长 int ls = (int) (result.getDuration() / 1000); if (ls > VIDEO_TIME) { //删除文件 file.delete(); return 0; } //截取视频的某一帧作为视频封面 这里的newFileName在上面已经定义好了 VideoUtil.fetchFrame(realVideoPath, newFileName.replace("/file", Global.getWebUploadPath + File.separator)); //视频路径 user.setVideoPath(videoPath); //视频压缩图路径 user.setCompressPath(newFileName); return 1; }

    以上是判断视频时长的主要代码,简单讲一下实现思路,首先是将视频保存到本地,通过工具类获取视频的时长,如果大于10秒,删除本地视频,然后返回错误信息。如果视频在10秒以内,截取视频某一帧作为视频封面图,这里还用到了FFmpeg工具,这个工具个人不是太熟悉。记录一下,方便下次使用。

    Processed: 0.009, SQL: 9