JAVA使用ffmpeg根據視頻時長截取視頻中N張圖片(附獲取視頻時長方法)
一、執行多次命令遍歷截取圖片
/**
* 遍歷截圖
* @param tempVideoPath 視頻路徑
* @param cutImgNum 截取圖片數量
*/
public void getVideoImg(String tempVideoPath, Integer cutImgNum) {
for (int i = 1; i < cutImgNum+1; i++) {
// 獲取視頻截取圖片
String cutImgPath = this.getVideoCutImg(tempVideoPath, i);
// TODO 這裏可以保存視頻截圖路徑
// TODO 還可以進行一些業務邏輯...
}
}
/**
* 視頻截圖
* @param tempVideoPath 視頻路徑
* @param cutImgNum 截取圖片數量
* @param index 第幾張圖
*/
public String getVideoCutImg(String tempVideoPath, Integer cutImgNum, Integer index) {
String resultStr = "";
try {
Long videoDuration = this.getVideoDuration(tempVideoPath);
long duration = (videoDuration / (cutImgNum+1)) * index;
log.error("上傳視頻路徑:tempVideoPath:{}, 視頻時長:videoDuration:{}", tempVideoPath, videoDuration);
// 從視頻中截取三張圖片
String tempImgPath = tempVideoPath.replace(".", "_")+"_cut_"+index+".jpg";
// 獲取腳本路徑
String command = "ffmpeg -i "+tempVideoPath+" -ss "+ (double) duration/1000+" -vframes 1 -f image2 "+tempImgPath;
log.info("視頻截取圖片 command:{}", command);
String rs = CommandUtil.run(command);
resultStr = tempImgPath;
log.info("視頻截取圖片 rs:{}", rs);
} catch (Exception e) {
log.error("視頻截取圖片異常! tempVideoPath:{}", tempVideoPath, e);
}
return resultStr;
}
二、執行一次命令獲取N張視頻截圖
執行該命令可能會存在一些權限問題,請確保有足夠的權限
/**
* 視頻截圖
* @param tempVideoPath 視頻路徑
* @param cutImgNum 截取圖片數量
*/
public String getVideoCutImg(String tempVideoPath, Integer cutImgNum) {
String resultStr = "";
try {
Integer n = cutImgNum + 1;
Long videoDuration = this.getVideoDuration(tempVideoPath);
double s = (double) videoDuration / 1000;
// 獲取總幀數(ffmpeg默認1秒爲24幀)
double total = s * 24;
log.error("上傳視頻路徑:tempVideoPath:{}, 視頻時長:videoDuration:{}", tempVideoPath, videoDuration);
// 從視頻中截取三張圖片
String tempImgPath = tempVideoPath.replace(".", "_")+"_cut_%2d.jpg";
// 獲取腳本路徑(between(?, ?) 函數爲 從第幾幀開始到結束,not(mod(?, ?) 函數爲 間隔多少幀截取一張圖))
String command = "ffmpeg -i "+tempVideoPath+" -vf select=between(n\\,"+((int)total/n + 1)+"\\,"+total+")*not(mod(n\\,"+(int)total/n+")) -vsync 2 -f image2 "+tempImgPath ;
log.info("視頻截取圖片 command:{}", command);
String rs = CommandUtil.run(command);
resultStr = tempImgPath;
log.info("視頻截取圖片 rs:{}", rs);
} catch (Exception e) {
log.error("視頻截取圖片異常! tempVideoPath:{}", tempVideoPath, e);
}
// TODO 可以根據圖片路徑格式去獲取截取後的圖片
return resultStr;
}
三、獲取視頻時長的方法
/**
* 獲取視頻時長
* @param viedoPath 視頻路徑
*/
public Long getVideoDuration(String viedoPath) {
Long rl;
try {
File video = new File(viedoPath);
Encoder encoder = new Encoder();
MultimediaInfo mi = encoder.getInfo(video);
rl = mi.getDuration();
} catch (Exception e) {
log.error("獲取視頻時長失敗! viedoPath:{}", viedoPath, e);
rl = null;
}
return rl;
}
需要添加的Maven座標
<dependency>
<groupId>fakepath</groupId>
<artifactId>axis</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>fakepath</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
</dependency>