增加视频文件生成关键帧图片的处理逻辑,以关键帧图片作为源文件生成特征文件。
This commit is contained in:
@@ -643,6 +643,8 @@ public final class Constants {
|
||||
public static final boolean SPEAKER_SAMPLE_PROC_PARAM_IS_TRANSLATION = Configurations.getBooleanProperty("speaker_sample_proc_param_is_translation", false);
|
||||
public static final boolean LOGO_SAMPLE_PROC_PARAM_IS_TRANSLATION = Configurations.getBooleanProperty("logo_sample_proc_param_is_translation", false);
|
||||
public static final boolean FACE_SAMPLE_PROC_PARAM_IS_TRANSLATION = Configurations.getBooleanProperty("face_sample_proc_param_is_translation", false);
|
||||
//视频文件生成关键帧图片相关参数
|
||||
public static final String VEDIO_TO_PICTURE_PROC = Configurations.getStringProperty("video_to_picture_proc", "./video_to_picture_proc");
|
||||
|
||||
//HTTP自定义域相关参数
|
||||
public static String HTTP_HEADER_USER_REGION_KEY=Configurations.getStringProperty("http_header_user_region_key", "HTTP_HEADER");
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.nis.web.controller.configuration.ntc;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -11,13 +15,18 @@ import java.util.UUID;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.filefilter.IOFileFilter;
|
||||
import org.apache.tools.zip.ZipOutputStream;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import com.nis.domain.FunctionRegionDict;
|
||||
@@ -34,16 +43,21 @@ import com.nis.exceptions.CallExternalProceduresException;
|
||||
import com.nis.exceptions.MaatConvertException;
|
||||
import com.nis.exceptions.MultiPartNewException;
|
||||
import com.nis.util.ConfigServiceUtil;
|
||||
import com.nis.util.Configurations;
|
||||
import com.nis.util.Constants;
|
||||
import com.nis.util.DictUtils;
|
||||
import com.nis.util.FileUtils;
|
||||
import com.nis.util.JsonMapper;
|
||||
import com.nis.util.StringUtil;
|
||||
import com.nis.util.StringUtils;
|
||||
import com.nis.web.controller.BaseController;
|
||||
import com.nis.web.security.UserUtils;
|
||||
import com.nis.web.security.SystemAuthorizingRealm.Principal;
|
||||
|
||||
import it.sauronsoftware.jave.AudioInfo;
|
||||
import it.sauronsoftware.jave.Encoder;
|
||||
import it.sauronsoftware.jave.EncoderException;
|
||||
import it.sauronsoftware.jave.InputFormatException;
|
||||
import it.sauronsoftware.jave.MultimediaInfo;
|
||||
import it.sauronsoftware.jave.VideoInfo;
|
||||
|
||||
@@ -123,20 +137,53 @@ public class AvController extends BaseController {
|
||||
//保存文件样例配置
|
||||
@RequestMapping(value = {"/sample/saveFileSample"})
|
||||
public String saveFileSample(Model model,HttpServletRequest request,HttpServletResponse response, RedirectAttributes redirectAttributes,
|
||||
String ids,AvFileSampleCfg entity,MultipartFile srcFile,MultipartFile sampleFile){
|
||||
String ids,AvFileSampleCfg entity,MultipartFile srcFile,MultipartFile sampleFile,String picPath,String videoToPicture){
|
||||
try{
|
||||
// if(srcFile!=null && sampleFile!=null &&
|
||||
// srcFile.getSize()>0 && sampleFile.getSize()>0){
|
||||
String sep = System.getProperty("file.separator");
|
||||
String srcFilePath = Constants.AV_FILE_PATH+entity.getCfgType()+sep+"srcFile";//源文件保存路径
|
||||
String sampleFilePath = Constants.AV_FILE_PATH+entity.getCfgType()+sep+"sampleFile";//样例文件保存路径
|
||||
String resultFilePath = Constants.AV_FILE_PATH+entity.getCfgType()+sep+"resultFile";//结果文件保存路径
|
||||
FileUtils.createDirectory(srcFilePath);
|
||||
FileUtils.createDirectory(sampleFilePath);
|
||||
String fileName = UUID.randomUUID()+"";
|
||||
|
||||
//视频样例生成并选中的图片压缩为zip文件
|
||||
if("true".equals(videoToPicture)){
|
||||
if(!StringUtils.isBlank(entity.getSrcPath())){
|
||||
String[] srcArray = entity.getSrcPath().split("\\|");//所选图片数组
|
||||
String srcFileAllPath = srcFilePath+sep+fileName+".zip";
|
||||
File zipFile = new File(srcFileAllPath);
|
||||
ZipOutputStream zouts = new ZipOutputStream(new FileOutputStream(zipFile));
|
||||
for(String s:srcArray){
|
||||
if(!"".equals(s)){
|
||||
String filePath = picPath+sep+s;
|
||||
File file = new File(filePath);
|
||||
//将文件添加至压缩文件
|
||||
FileUtils.zipFilesToZipFile(file.getParent(), file, zouts);
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
if(zouts!=null){
|
||||
zouts.close();
|
||||
}
|
||||
FileInputStream input = new FileInputStream(srcFileAllPath);
|
||||
srcFile = new MockMultipartFile(zipFile.getName(), input);
|
||||
if(input!=null){
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(srcFile!=null && srcFile.getSize()>0 && entity!=null){
|
||||
String sep = System.getProperty("file.separator");
|
||||
String srcFilePath = Constants.AV_FILE_PATH+entity.getCfgType()+sep+"srcFile";//源文件保存路径
|
||||
String sampleFilePath = Constants.AV_FILE_PATH+entity.getCfgType()+sep+"sampleFile";//样例文件保存路径
|
||||
String resultFilePath = Constants.AV_FILE_PATH+entity.getCfgType()+sep+"resultFile";//结果文件保存路径
|
||||
FileUtils.createDirectory(srcFilePath);
|
||||
FileUtils.createDirectory(sampleFilePath);
|
||||
String srcFileAllPath = "";
|
||||
if(StringUtil.isBlank(srcFile.getOriginalFilename())){
|
||||
srcFileAllPath = srcFilePath+sep+fileName+FileUtils.getSuffix(srcFile.getName(), true);
|
||||
}else{
|
||||
srcFileAllPath = srcFilePath+sep+fileName+FileUtils.getSuffix(srcFile.getOriginalFilename(), true);
|
||||
}
|
||||
|
||||
String fileName = UUID.randomUUID()+"";
|
||||
String srcFileAllPath = srcFilePath+sep+fileName+FileUtils.getSuffix(srcFile.getOriginalFilename(), true);
|
||||
String sampleFileAllPath = sampleFilePath+sep+fileName+".sample";
|
||||
String resultFileAllPath = resultFilePath+sep+fileName+".result";
|
||||
entity.setSrcPath(srcFileAllPath);
|
||||
@@ -144,8 +191,9 @@ public class AvController extends BaseController {
|
||||
entity.setResultPath(resultFileAllPath);
|
||||
|
||||
File uploadSrcFile = new File(srcFileAllPath);
|
||||
// File uploadSampleFile = new File(sampleFileAllPath);
|
||||
FileCopyUtils.copy(srcFile.getBytes(), uploadSrcFile);//保存源文件
|
||||
if(!uploadSrcFile.exists()){
|
||||
FileCopyUtils.copy(srcFile.getBytes(), uploadSrcFile);//保存源文件
|
||||
}
|
||||
entity.setSrcUrl("");
|
||||
entity.setSampleUrl("");
|
||||
/*String host = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
|
||||
@@ -158,40 +206,33 @@ public class AvController extends BaseController {
|
||||
entity.setSrcUrl(srcUrl);
|
||||
entity.setSampleUrl(sampleUrl);*/
|
||||
|
||||
// File uploadSrcFile = new File(srcFilePath);
|
||||
// FileCopyUtils.copy(srcFile.getBytes(), uploadSrcFile);
|
||||
// String srcMd5 = FileUtils.getFileMD5(uploadSrcFile);
|
||||
// File uploadSampleFile = new File(sampleFilePath);
|
||||
// String sampleMd5 = FileUtils.getFileMD5(uploadSampleFile);
|
||||
// File uploadSrcFile = new File(srcFilePath);
|
||||
// FileCopyUtils.copy(srcFile.getBytes(), uploadSrcFile);
|
||||
// String srcMd5 = FileUtils.getFileMD5(uploadSrcFile);
|
||||
// File uploadSampleFile = new File(sampleFilePath);
|
||||
// String sampleMd5 = FileUtils.getFileMD5(uploadSampleFile);
|
||||
|
||||
// entity.setSrcMd5(srcMd5);
|
||||
// entity.setSampleMd5(sampleMd5);
|
||||
// entity.setSrcMd5(srcMd5);
|
||||
// entity.setSampleMd5(sampleMd5);
|
||||
|
||||
//音频、视频、VoIP、说话人(音频)、人脸识别(视频)样例需要验证时长
|
||||
if(entity.getCfgType().equals(Constants.AV_SAMPLE_AUDIO_REGION)
|
||||
|| entity.getCfgType().equals(Constants.AV_SAMPLE_VIDEO_REGION)
|
||||
|| entity.getCfgType().equals(Constants.AV_SAMPLE_VOIP_REGION)
|
||||
|| entity.getCfgType().equals(Constants.MM_SPEAKER_RECOGNIZATION_REGION)
|
||||
|| entity.getCfgType().equals(Constants.MM_FACE_RECOGNIZATION_REGION)){
|
||||
//验证音视频文件时长
|
||||
Encoder encoder = new Encoder();
|
||||
String length = "";
|
||||
MultimediaInfo m = encoder.getInfo(uploadSrcFile);
|
||||
long ls = m.getDuration()/1000;
|
||||
int hour = (int) (ls/3600);
|
||||
int minute = (int) (ls%3600)/60;
|
||||
int second = (int) (ls-hour*3600-minute*60);
|
||||
length = hour+"'"+minute+"''"+second+"'''";
|
||||
logger.info(uploadSrcFile.getName()+"时长:"+length);
|
||||
if(ls>0 && second>Constants.AV_DURATION_LIMIT){
|
||||
if(Constants.AUDIO_FILE_TYPE.contains(FileUtils.getSuffix(uploadSrcFile.getName(),false))
|
||||
||Constants.VIDEO_FILE_TYPE.contains(FileUtils.getSuffix(uploadSrcFile.getName(),false))
|
||||
||Constants.VOIP_FILE_TYPE.contains(FileUtils.getSuffix(uploadSrcFile.getName(),false))
|
||||
||Constants.SPEAKER_FILE_TYPE.contains(FileUtils.getSuffix(uploadSrcFile.getName(),false))
|
||||
||Constants.FACE_FILE_TYPE.contains(FileUtils.getSuffix(uploadSrcFile.getName(),false))
|
||||
){
|
||||
if(!validateAvDuration(uploadSrcFile)){
|
||||
addMessage(redirectAttributes,"exceeds_duration_limit");
|
||||
logger.error("The duration of uploaded files exceeds the limit("+Constants.AV_DURATION_LIMIT+"s).");
|
||||
throw new MultiPartNewException(this.getMsgProp().getProperty("exceeds_duration_limit"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
avCfgService.saveOrUpdateAvFileSample(entity, srcFile);
|
||||
addMessage(redirectAttributes,"save_success");
|
||||
|
||||
@@ -229,7 +270,7 @@ public class AvController extends BaseController {
|
||||
@RequestMapping(value = {"/sample/updateAvFileSampleValid"})
|
||||
public String updateAvFileSampleValid(Integer isAudit,Integer isValid,String ids,Integer functionId,RedirectAttributes redirectAttributes){
|
||||
avCfgService.updateAvFileSampleValid(isAudit,isValid,ids);
|
||||
addMessage(redirectAttributes,"delete_failed");
|
||||
addMessage(redirectAttributes,"delete_success");
|
||||
return "redirect:" + adminPath +"/ntc/av/sample/fileSampleList?functionId="+functionId;
|
||||
}
|
||||
//修改文件样例配置审核状态
|
||||
@@ -466,4 +507,115 @@ public class AvController extends BaseController {
|
||||
//return "redirect:" + adminPath +"/ntc/iplist/list?functionId="+entity.getFunctionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证音视频时长
|
||||
* @throws EncoderException
|
||||
* @throws InputFormatException
|
||||
*/
|
||||
public boolean validateAvDuration(File file) throws InputFormatException, EncoderException{
|
||||
//验证音视频文件时长
|
||||
Encoder encoder = new Encoder();
|
||||
String length = "";
|
||||
MultimediaInfo m = encoder.getInfo(file);
|
||||
long ls = m.getDuration()/1000;
|
||||
int hour = (int) (ls/3600);
|
||||
int minute = (int) (ls%3600)/60;
|
||||
int second = (int) (ls-hour*3600-minute*60);
|
||||
length = hour+"'"+minute+"''"+second+"'''";
|
||||
logger.info(file.getName()+"时长:"+length);
|
||||
if(ls>0 && second>Constants.AV_DURATION_LIMIT){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 上传视频文件,调用脚本生成关键帧图片,返回图片保存路径
|
||||
* @param cfg
|
||||
* @param functionId
|
||||
* @param redirectAttributes
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value = {"/sample/videoToPicture"})
|
||||
public Map videoToPicture(Model model,@RequestParam("srcFile") CommonsMultipartFile srcFile){
|
||||
|
||||
String sep = System.getProperty("file.separator");
|
||||
String random = UUID.randomUUID()+"";
|
||||
String srcFilePath = Constants.AV_FILE_PATH+"video"+sep+"srcFile";//视频源文件保存路径
|
||||
String picFilePath = StringUtils.getUserfilesBaseDir()+"video"+sep+"picFile";//视频生成的关键帧图片文件保存路径
|
||||
|
||||
FileUtils.createDirectory(srcFilePath);
|
||||
FileUtils.createDirectory(picFilePath);
|
||||
String srcFileAllPath = srcFilePath+sep+random+FileUtils.getSuffix(srcFile.getOriginalFilename(), true);//新的文件名
|
||||
File uploadSrcFile = new File(srcFileAllPath);
|
||||
Map map = new HashMap();
|
||||
map.put("picFilePath", picFilePath);
|
||||
try {
|
||||
FileCopyUtils.copy(srcFile.getBytes(), uploadSrcFile);//保存源文件
|
||||
if(validateAvDuration(uploadSrcFile)){
|
||||
String shellName = Constants.VEDIO_TO_PICTURE_PROC;
|
||||
// String params = srcFileAllPath+" "+picFilePath+" 0.95 90.0 0.5";
|
||||
String params = srcFileAllPath+" "+picFilePath;
|
||||
Map resultMap = avCfgService.execShell(shellName, params);
|
||||
if(resultMap.get("exitStatus").equals(0)){//调用外部程序成功
|
||||
//关键帧图片生成成功,删除原视频文件
|
||||
FileUtils.deleteFile(srcFileAllPath);
|
||||
map.put("status", 1);
|
||||
map.put("msg", "success");
|
||||
}
|
||||
}else{
|
||||
map.put("status", 0);
|
||||
map.put("msg", this.getMsgProp().get("exceeds_duration_limit"));
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
map.put("status", 0);
|
||||
map.put("msg", e.getMessage());
|
||||
} catch (InputFormatException e) {
|
||||
e.printStackTrace();
|
||||
map.put("status", 0);
|
||||
map.put("msg", e.getMessage());
|
||||
} catch (EncoderException e) {
|
||||
e.printStackTrace();
|
||||
map.put("status", 0);
|
||||
map.put("msg", e.getMessage());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@RequestMapping(value = {"/sample/selectVedioPicture"})
|
||||
public String selectVedioPicture(Model model,HttpServletRequest request,String picFilePath,String srcPath){
|
||||
Collection<File> files = FileUtils.listFiles(new File(picFilePath), null, true);
|
||||
List<Map<String,String>> fileList = new ArrayList();
|
||||
String picUrl = picFilePath.substring(picFilePath.indexOf(Configurations.getStringProperty("userfiles.basedir", "upload")));
|
||||
String sep = System.getProperty("file.separator");
|
||||
String[] checkedPic = null;
|
||||
if(srcPath!=null){
|
||||
checkedPic = srcPath.split("\\|");
|
||||
}
|
||||
for(File f:files){
|
||||
Map map = new HashMap();
|
||||
map.put("picUrl", StringUtils.replace(picUrl+"/"+f.getName(), "\\", "/"));
|
||||
map.put("picName", f.getName());
|
||||
boolean checked = false;
|
||||
if(checkedPic!=null){
|
||||
for(String pic:checkedPic){
|
||||
if(f.getName().equals(pic)){
|
||||
checked = true;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
checked = true;//默认全选
|
||||
}
|
||||
|
||||
map.put("checked", checked);
|
||||
fileList.add(map);
|
||||
}
|
||||
model.addAttribute("fileList", fileList);
|
||||
model.addAttribute("picFilePath",picFilePath);
|
||||
return "/cfg/av/videoPictureList";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user