获取视频信息,截取视频指定帧作为封面图

1.pom添加依赖

	    <dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>javacv</artifactId>
			<version>1.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>javacpp</artifactId>
			<version>1.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.bytedeco.javacpp-presets</groupId>
			<artifactId>opencv</artifactId>
			<version>3.4.1-1.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.bytedeco.javacpp-presets</groupId>
			<artifactId>opencv</artifactId>
			<version>3.4.1-1.4.1</version>
			<classifier>linux-x86_64</classifier>
		</dependency>
		<dependency>
			<groupId>org.bytedeco.javacpp-presets</groupId>
			<artifactId>ffmpeg</artifactId>
			<version>3.4.2-1.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.bytedeco.javacpp-presets</groupId>
			<artifactId>ffmpeg</artifactId>
			<version>3.4.2-1.4.1</version>
			<classifier>linux-x86_64</classifier>
		</dependency>

2.根据上传的文件流,创建本地文件 - 这里首先是先写一个创建文件/文件夹的方法.

	/**
	 * @Description: 根据不同情况创建文件夹或者文件(适用于不同的操作平台,注意:Linux上需要先拥有在文件夹下进行操作的权限)方法
	 * @Param: folderPath文件夹路径(不传递指定文件夹则默认为项目存储的文件夹中,若传递,格式请保持为: D:/1555555/20200605/).
	 *         fileName文件名(不传递指定文件名,则方法内会自动生成一个文件名).
	 *         fileType生成的文件具体格式(如果文件名自带后缀则fileType可为空).
	 * @return: 返回String. 文件夹路径/文件路径,创建的是什么则返回什么
	 * @Author: liu_yan
	 * @Date: 2018/11/15
	 */
	public static String operatingPlatform(String folderPath, String fileName, String fileType) {
		try {
			// 获取分隔符,随操作系统不同而不同
			String separator = "/";
			String userDir =System.getProperties().getProperty("user.dir").replace("\\","/") + separator;

			// 如果传递了文件夹路径.则以传递的路径为基准创建文件夹(举例:windows - D:/1555555/20200605; linux - /usr/local/20200605 )
			if (StringUtils.isNotEmpty(folderPath)) {
				userDir = folderPath;
				File file = new File(folderPath);
				if (!file.exists()) file.mkdirs();// 如果文件夹不存在,则创建(注意:如果是Linux这一步可能出错,可能没有文件夹创建权限,注意)
			}
			System.out.println("************文件夹路径:"+folderPath+"************");

			/*
			 * 以下预计了几种情况:
			 * 1.fileName为空,fileType不为空,则则以当前时间精确到毫秒值+当前时间的纳秒值为文件名创建文件
			 * 2.fileName不为空. 则先判断是否自带后缀(如果有后缀,则不管它是否传递了fileType都直接用文件名,
			 * 如果没有后缀,则用传递进来的fileType作为后缀,要是fileType都没有.那就不创建文件了.)
			 */
			boolean flag = false;
			if (StringUtils.isEmpty(fileName) && StringUtils.isNotEmpty(fileType)) {
				String yyyyMMdd = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
				long nanosecond = System.nanoTime();
				fileName = yyyyMMdd + nanosecond + "." + fileType;
				userDir = userDir + fileName;
				flag = true;
			} else if (StringUtils.isNotEmpty(fileName)) {
				//检查传递进来的fileName是否自带后缀
				int lastIndexOf = fileName.lastIndexOf(".");
				if(lastIndexOf>0){//表示文件名自带后缀
					userDir = userDir + fileName;
					flag = true;
				}else {
					if(StringUtils.isNotEmpty(fileType)){//文件名无后缀,则必须要传递进fileType
						userDir = userDir + fileName + "." + fileType;
						flag = true;
					}
				}
			}

			//if true表示需要创建文件
			if(flag){
				File file1 = new File(userDir);
				if (!file1.exists()) file1.createNewFile();// 如果不存在该文件,则创建
			}
			return userDir;
		} catch (Exception e) {
			e.printStackTrace();
			return "false";
		}
	}

2-1. 将后台获取到的上传视频的流,装载到调用上面方法得到的空白文件中(生成本地文件)

String mp4= operatingPlatform("", "", "MP4");

doc.transferTo(new File(mp4));// doc - MultipartFile doc

3. 调用引入的jar包中提供的解析视频信息的方法, 这里仅获取视频宽高,及抓取视频某一帧作为封面图

	public static void grabPic(InputStream file,Map<String,Object> resultMap) throws Exception{
		FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
		ff.start();
		// 获取到视频宽高.
		int imageHeight = ff.getImageHeight();
		int imageWidth = ff.getImageWidth();
		resultMap.put("height", imageHeight);
		resultMap.put("width",  imageWidth);

		// 截取视频中图片
		String framefile = operatingPlatform("","","jpg");
		File targetFile = new File(framefile);

		int i = 0;
		Frame frame = null;
		int lenght = ff.getLengthInFrames()/2;
		while (i < lenght) {// 选取帧数
			frame = ff.grabFrame();
			if (frame.image != null) break;
			i++;
		}

		Java2DFrameConverter converter =new Java2DFrameConverter();
		BufferedImage srcBi =converter.getBufferedImage(frame);
		try {
			boolean write = ImageIO.write(srcBi, "jpg", targetFile);
			resultMap.put("relativePath",framefile);
		}catch (Exception e) {
			e.printStackTrace();
		}
		ff.stop();
	}

4.  准备一个装载返回信息的Map, 获取本地文件输入流, 开始调用方法.

Map<String, Object> map = new HashMap<String, Object>();
InputStream ins = new FileInputStream(new File(mp4));
grabPic(ins, map);

 

注: 以上简单讲就是两个方法, 一个创建本地文件,一个调用第三方提供的方法获取视频信息, 中间夹杂一点代码.

    温馨提示:  关闭IO流, 删除创建的本地文件.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值