2021SC@SDUSC
对视频文件的处理封装在类MediaFilePreviewImpl中,包含filePreviewHandle文件预览处理、convertUrl检查视频文件处理逻辑、checkNeedConvert检查是否需要转换、convertToMp4遇到浏览器无法处理的视频格式时将视频格式转换为MP4。
目录
1、文件预览处理
首先根据url判断文件是不是浏览器可以直接访问的(是http开头),若不是则调用DownloadUtils工具类中的downLoad方法将文件下载到本地,之后调用BaseUrlFilter工具类的getBaseUrl() 方法和fileHandlerService的getRelativePath方法获取下载后的url,并赋给fileAttribute文件属性对象方便日后调用。
之后调用类中的checkNeedConvert方法检查文件是否需要转换,若需要则调用convertUrl检查视频逻辑并返回处理后的url。若是正常的视频类型,说明不需要转换,调用ConfigConstants的getMedia()方法获取视频类型。
进入for循环,通过判断文件属性后缀media.equals(fileAttribute.getSuffix())来判断文件是否系统可以处理的视频类型,并返回 MEDIA_FILE_PREVIEW_PAGE,若循环结束后都不存在匹配,则返回“暂不支持该文件类型”。
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
// 不是http开头,浏览器不能直接访问,需下载到本地
if (url != null && !url.toLowerCase().startsWith("http")) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName());
if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
} else {
url=BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent());
fileAttribute.setUrl(url);
}
}
if(checkNeedConvert(fileAttribute.getSuffix())){
url=convertUrl(fileAttribute);
}else{
//正常media类型
String[] medias = ConfigConstants.getMedia();
for(String media:medias){
if(media.equals(fileAttribute.getSuffix())){
model.addAttribute("mediaUrl", url);
return MEDIA_FILE_PREVIEW_PAGE;
}
}
return otherFilePreview.notSupportedFile(model, fileAttribute, "暂不支持");
}
model.addAttribute("mediaUrl", url);
return MEDIA_FILE_PREVIEW_PAGE;
}
2、处理视频文件
首先判断系统可以转换的文件中是否包含该文件类型,若包含则根据url直接转换,若不包含则调用convertToMp4(fileAttribute)方法将该文件加入缓存之后再调用 fileHandlerService的addConvertedMedias(url,convertedUrl)将文件加入浏览列表中,最后返还转换过后的url。
/**
* 检查视频文件处理逻辑
* 返回处理过后的url
* @return url
*/
private String convertUrl(FileAttribute fileAttribute) {
String url = fileAttribute.getUrl();
if(fileHandlerService.listConvertedMedias().containsKey(url)){
url= fileHandlerService.getConvertedMedias(url);
}else{
if(!fileHandlerService.listConvertedMedias().containsKey(url)){
synchronized(LOCK){
if(!fileHandlerService.listConvertedMedias().containsKey(url)){
String convertedUrl=convertToMp4(fileAttribute);
//加入缓存
fileHandlerService.addConvertedMedias(url,convertedUrl);
url=convertedUrl;
}
}
}
}
return url;
}3、将不兼容格式转换成MP4
/**
* 将浏览器不兼容视频格式转换成MP4
* @param fileAttribute
* @return
*/
private static String convertToMp4(FileAttribute fileAttribute) {
//说明:这里做临时处理,取上传文件的目录
String homePath = ConfigUtils.getHomePath();
String filePath = homePath+File.separator+"file"+File.separator+"demo"+File.separator+fileAttribute.getName();
String convertFileName=fileAttribute.getUrl().replace(fileAttribute.getSuffix(),"mp4");
File file=new File(filePath);
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
String fileName = null;
Frame captured_frame = null;
FFmpegFrameRecorder recorder = null;
try {
fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4");
File desFile=new File(fileName);
//判断一下防止穿透缓存
if(desFile.exists()){
return fileName;
}
frameGrabber.start();
recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264 //AV_CODEC_ID_MPEG4
recorder.setFormat("mp4");
recorder.setFrameRate(frameGrabber.getFrameRate());
//recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
recorder.setSampleRate(frameGrabber.getSampleRate());
recorder.setAudioChannels(frameGrabber.getAudioChannels());
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.start();
while ((captured_frame = frameGrabber.grabFrame()) != null) {
try {
recorder.setTimestamp(frameGrabber.getTimestamp());
recorder.record(captured_frame);
} catch (Exception e) {
}
}
recorder.stop();
recorder.release();
frameGrabber.stop();
} catch (Exception e) {
e.printStackTrace();
}
//是否删除源文件
//file.delete();
return convertFileName;
}4、检查视频文件是否需要转换
/**
* 检查视频文件转换是否已开启,以及当前文件是否需要转换
* @return
*/
private boolean checkNeedConvert(String suffix) {
//1.检查开关是否开启
if("false".equals(ConfigConstants.getMediaConvertDisable())){
return false;
}
//2.检查当前文件是否需要转换
String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
String type = suffix;
for(String temp : mediaTypesConvert){
if(type.equals(temp)){
return true;
}
}
return false;
}