用Java代码提取视频的缩略图的两种办法
来源:互联网 发布:淘宝第三方服务退款 编辑:程序博客网 时间:2024/06/01 10:50
用Java代码提取视频的缩略图的两种办法
今天项目中有个需求,让在后台用Java提取每一个视频的缩略图,然后将图片传给前端页面。在网上搜了一下,发现基本上都是使用ffmpeg工具来进行视频格式转换和提取视频缩略图,这个方法的好处在于代码简单易懂且运行速度快,缺点在于对于已上线的项目来说,在服务器上更新代码时需要装ffmpeg工具,比较麻烦。还有一种方法是使用Javacv来提取视频某些帧的图片并进行保存,此方法的好处在于只用导入Javacv相关的架包而不用安装工具,缺点在于代码稍显复杂且很容易因为几个架包的版本问题而导致编译不通过或者抛classNotFound异常(这个问题困扰了我一下午,下面我会给出解决方案)而且运行速度较慢(测了几个帧都在5秒左右)。下面就是两个方案的具体实现。
一、使用ffmpeg工具:
ffmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量。
首先要下载ffmpeg工具,下载地址:https://ffmpeg.zeranoe.com/builds/,然后把该文件到bin目录的路径加到环境变量的Path中。
然后就编写如下代码:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void handler(String ffmpegPath,String upFilePath,String mediaPicPath){
List cutpic = new ArrayList();
cutpic.add(ffmpegPath); // 视频提取工具的位置
cutpic.add(“-i”); // 添加参数"-i",该参数指定要转换的文件
cutpic.add(upFilePath); // 视频文件路径
cutpic.add(“-y”);
cutpic.add(“-f”);
cutpic.add(“image2”);
cutpic.add(“-ss”); // 添加参数"-ss",该参数指定截取的起始时间
cutpic.add(“1”); // 添加起始时间为第1秒
cutpic.add(“-t”); // 添加参数"-t",该参数指定持续时间
cutpic.add(“0.001”); // 添加持续时间为1毫秒
cutpic.add(“-s”); // 添加参数"-s",该参数指定截取的图片大小
cutpic.add(“800*600”); // 添加截取的图片大小为800*600
cutpic.add(mediaPicPath); // 添加截取的图片的保存路径
boolean mark = true; ProcessBuilder builder = new ProcessBuilder(); try { builder.command(cutpic); builder.redirectErrorStream(true); // 如果此属性为 true,则任何由通过此对象的 start() 方法启动的后续子进程生成的错误输出都将与标准输出合并, //因此两者均可使用 Process.getInputStream() 方法读取。这使得关联错误消息和相应的输出变得更容易 builder.start(); } catch (Exception e) { mark = false; System.out.println(e); e.printStackTrace(); } } public static void main(String[] args){ handler("D:/ffmpeg-20170811-5859b5b-win64-static/bin/ffmpeg.exe","http://wemewtest.oss-cn-qingdao.aliyuncs.com/2017-06-08-14/wKPPSfepDZ.mp4","D:/new/test7.jpg"); }
}
了解更多ffmpeg内容可以参照:http://www.tuicool.com/articles/fMRRZvY
二、使用Javacv
一开始我手动导的架包,如下:
有可能是架包版本问题,一直抛classNotFound异常,怎么试都不行,后面我新建了一个项目,用mawen进行自动导包,马上就解决了,看图
只用在pom.xml配置依赖
<dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>0.8</version> </dependency>
导入0.8版本的javacv就行,mawen会自动将相关的架包导进来。下面是代码:
package com.aliyun.mts;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
public class Test {
/** * 获取指定视频的帧并保存为图片至指定目录 * @param videofile 源视频文件路径 * @param framefile 截取帧的图片存放路径 * @throws Exception */public static void fetchFrame(String videofile, String framefile) throws Exception { long start = System.currentTimeMillis(); 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.flush(); ff.stop(); System.out.println(System.currentTimeMillis() - start);}public static void main(String[] args) { try { Test.fetchFrame("http://wemewtest.oss-cn-qingdao.aliyuncs.com/2017-06-08-14/wKPPSfepDZ.mp4", "D:/new/test4.jpg"); } catch (Exception e) { e.printStackTrace(); }}
}
- 用Java代码提取视频的缩略图的两种办法
- java 图片缩略图的两种方法
- java 图片缩略图的两种方法
- iOS截取视频缩略图的两种方法
- java生成视频的缩略图
- Java+ffmpeg 视频转码+缩略图提取
- Java 生成缩略图的代码
- 获取视频的缩略图
- 获取视频的缩略图
- 获取视频的缩略图
- 获取视频的缩略图
- 用gstreamer抓取视频的缩略图
- java除法保持小数点后位数的两种办法
- java结构体排序的两种办法
- java结构体排序的两种办法
- 批量提取文件名的办法
- 网页上的视频缩略图
- FFmpeg获得视频的缩略图
- C语言文件操作
- Java中的锁分类
- emlog编辑器探寻之旅
- [笔记分享] [SD] SD读写测试程序
- java中四种操作(DOM、SAX、JDOM、DOM4J)xml方式详解与比较
- 用Java代码提取视频的缩略图的两种办法
- array address
- 给初学者的RxJava2.0教程(三)
- 洛谷P3049 [USACO12MAR]园林绿化Landscaping
- Spring Ioc创建之BeanFactory创建源码分析
- Canvas 语法
- Linux学习笔记(五)-----基本dos命令,Vi编辑器,压缩解压命令
- 死锁及解决办法
- Apache Commons这个类库有哪些作用