JPG图片转视频
- 需要引入的依赖Jim2mov 和 Jmf
我的Jim2mov是从官网下载 然后放到本地仓库
Jmf可以直接maven引入,也可以从官网下载
<!-- 图片转视频 -->
<dependency>
<groupId>javax.media</groupId>
<artifactId>jmf</artifactId>
<version>2.1.1e</version>
</dependency>
<dependency>
<groupId>com.cyf</groupId>
<artifactId>Jim2mov</artifactId>
<version>1.0.0</version>
</dependency>
- 传入文件路径,获取文件路径下的image文件夹下的文件。
⚠️ 视频的宽度和高度必须和生成视频的宽高相同,否则生成的视频不能播放!!!
public static void imageToMov(String imagePath){
File imageDir = new File(imagePath+File.separator+"image");
File[] files = imageDir.listFiles();
// 每秒播放的帧数
int fps = 10;
// 视频的宽度
int mWidth = 640;
// 视频的高度
int mHeight = 480;
//视频名称(视频的后缀为mov或则mp4都可以,都是可以播放的)
String aviFileName = imagePath+".mp4";
boolean result = convertPicToAvi(files, aviFileName, fps, mWidth, mHeight);
if (result){
deleteImages(imagePath);
}
}
- 生成视频
- springBoot项目启动报错:
java.awt.HeadlessException
配置项目启动类的VM options :-Djava.awt.headless=false
- 但是如果打成jar包这个配置是不会被打包的,所以最好使用代码配置。在项目启动类中写:
System.setProperty("java.awt.headless","false");
SpringApplication.run(ParkingLotApplication.class, args);
- 在开发时用的是Mac开发的,当时测试是没有问题的,但是最后在windows电脑跑的时候,会报找不到
Error instantiating class: com.sun.media.processor.E.Handler
处理类。中间那个E是我当时传入的文件夹的盘符其实,它需要找到的处理类应该是:com.sun.media.processor.file.Handle
。报错位置:
通过看源码分析:
是在创建这个实体的时候,它根据createMediaLocator这个方法
//是在创建这个实体的是否,它根据createMediaLocator这个方法判断
public DefaultMovieInfoProvider(String fileToSave) {
this(MovieUtils.createMediaLocator(fileToSave));
}
可以清楚的看到,它创建对象的时候会根据传的路径去判断,mac和linux的文件路径格式和windows是不同的,mac和linux没有盘符一说,那么在下面那个方法中会走第一个else里的判断,创建的MediaLocator中的对象
/**
* 这个是上面那个方法里面的代码,我直接粘贴过来看到清楚
*/
public static MediaLocator createMediaLocator(String url) {
MediaLocator ml;
if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null) {
return ml;
} else {
if (url.startsWith(File.separator)) {
if ((ml = new MediaLocator("file:" + url)) != null) {
return ml;
}
} else {
String file = "file:" + System.getProperty("user.dir") + File.separator + url;
if ((ml = new MediaLocator(file)) != null) {
return ml;
}
}
return null;
}
}
我们再看下创建完MediaLocator对象后,在报错位置的调用此方法获取处理类的。
public String getProtocol() {
String protocol = "";
//58是“:”号,是截取冒号前
int colonIndex = this.locatorString.indexOf(58);
if (colonIndex != -1) {
protocol = this.locatorString.substring(0, colonIndex);
}
return protocol;
}
所以我在创建 DefaultMovieInfoProvider 实体的时候,给文件路径前加了"file:"。
DefaultMovieInfoProvider dmip = new DefaultMovieInfoProvider("file:"+aviFileName
);
- 生成视频方法完整代码:
/**
* 将图片转换成视频
*
* @param jpgs jpg图片
* @param aviFileName 生成的avi视频文件名
* @param fps 每秒帧数
* @param mWidth 视频的宽度
* @param mHeight 视频的高度
* @throws Exception
*/
public static boolean convertPicToAvi(File[] jpgs, String aviFileName, int fps, int mWidth, int mHeight) {
// jpgs目录放置jpg图片,图片文件名为(1.jpg,2.jpg...)
if (jpgs == null || jpgs.length == 0) {
log.info("没有找到图片文件");
return false;
}
// 对文件名进行排序
Arrays.sort(jpgs);
// 生成视频的名称
DefaultMovieInfoProvider dmip = new DefaultMovieInfoProvider("file:"+aviFileName);
// 设置每秒帧数 ,如果未设置,默认为3
dmip.setFPS(fps > 0 ? fps : 3);
// 设置总帧数
dmip.setNumberOfFrames(jpgs.length);
// 设置视频宽和高(最好与图片宽高保持一直)
// 如果未设置,默认为640*480
dmip.setMWidth(mWidth > 0 ? mWidth : 640);
dmip.setMHeight(mHeight > 0 ? mHeight : 480);
try {
Jim2Mov jim2Mov = new Jim2Mov(new ImageProvider() {
@Override
public byte[] getImage(int frame) {
try {
// 设置压缩比
return MovieUtils.convertImageToJPEG((jpgs[frame]), 1.0f);
} catch (IOException e) {
log.error("图片转JPEG异常,{}", e.getMessage());
e.printStackTrace();
}
return null;
}
}, dmip, null);
jim2Mov.saveMovie(MovieInfoProvider.TYPE_QUICKTIME_JPEG);
log.info("create mov success.");
return true;
} catch (MovieSaveException e) {
log.error("视频保存异常:{}",e.getMessage());
e.printStackTrace();
}
return false;
}
- 最后我会删除了生成视频的图片
/**
* 删除图片
* @param url
*/
public static void deleteImages(String url){
Path path = Paths.get(url);
try {
Files.walkFileTree(path,
new SimpleFileVisitor<Path>() {
// 先去遍历删除文件
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
// 再去遍历删除目录
@Override
public FileVisitResult postVisitDirectory(Path dir,
IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
}
);
}catch (IOException e){
log.error("文件删除异常:{}",e.getMessage());
e.printStackTrace();
}
}
最后提示下:⚠️目前生成的视频格式是Photo - JPEG 但是如果想要使用浏览器播放编码格式必须是H264或者H265好像都可以的,现在看jim2mov里没有生成这个格式的。想要转编码格式的话还需要使用ffmpeg解编码器。
因为这块相关的东西比较少,在开发过程中比较困难,所以还是要学会读源码,有时候比百度靠谱,哈哈,以上代码有些处理方式不知道对不对,但是都是可用的哦,有不对的地方,还得指出下,我学习学习😁。