| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- package cn.keking.service.impl;
- import cn.keking.config.ConfigConstants;
- import cn.keking.model.FileAttribute;
- import cn.keking.model.FileType;
- import cn.keking.model.ReturnResponse;
- import cn.keking.service.FileHandlerService;
- import cn.keking.service.FilePreview;
- import cn.keking.utils.DownloadUtils;
- import org.bytedeco.ffmpeg.global.avcodec;
- import org.bytedeco.javacv.FFmpegFrameGrabber;
- import org.bytedeco.javacv.FFmpegFrameRecorder;
- import org.bytedeco.javacv.Frame;
- import org.springframework.stereotype.Service;
- import org.springframework.ui.Model;
- import org.springframework.util.ObjectUtils;
- import java.io.File;
- /**
- * @author : kl
- * @authorboke : kailing.pub
- * @create : 2018-03-25 上午11:58
- * @description:
- **/
- @Service
- public class MediaFilePreviewImpl implements FilePreview {
- private final FileHandlerService fileHandlerService;
- private final OtherFilePreviewImpl otherFilePreview;
- private static final String mp4 = "mp4";
- public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
- this.fileHandlerService = fileHandlerService;
- this.otherFilePreview = otherFilePreview;
- }
- @Override
- public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
- String fileName = fileAttribute.getName();
- String suffix = fileAttribute.getSuffix();
- String cacheName = fileAttribute.getcacheName();
- String outFilePath = fileAttribute.getoutFilePath();
- boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
- String fileKey = fileAttribute.getFileKey();
- FileType type = fileAttribute.getType();
- String[] mediaTypesConvert = FileType.MEDIACONVERT_TYPES_CONVERT; //获取支持的转换格式
- boolean mediaTypes = false;
- for(String temp : mediaTypesConvert){
- if (suffix.equals(temp)) {
- mediaTypes = true;
- break;
- }
- }
- if(!url.toLowerCase().startsWith("http") || checkNeedConvert(mediaTypes)){ //不是http协议的 // 开启转换方式并是支持转换格式的
- if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) { //查询是否开启缓存
- ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
- if (response.isFailure()) {
- return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
- }
- String filePath = response.getContent();
- String convertedUrl = null;
- try {
- if(mediaTypes){
- convertedUrl=convertToMp4(filePath,outFilePath,fileKey);
- }else {
- convertedUrl =outFilePath; //其他协议的 不需要转换方式的文件 直接输出
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (convertedUrl == null ) {
- return otherFilePreview.notSupportedFile(model, fileAttribute, "视频转换异常,请联系管理员");
- }
- if (ConfigConstants.isCacheEnabled()) {
- // 加入缓存
- fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
- }
- model.addAttribute("mediaUrl", fileHandlerService.getRelativePath(outFilePath));
- }else{
- model.addAttribute("mediaUrl", fileHandlerService.listConvertedFiles().get(cacheName));
- }
- return MEDIA_FILE_PREVIEW_PAGE;
- }
- if(type.equals(FileType.MEDIA)){ // 支持输出 只限默认格式
- model.addAttribute("mediaUrl", url);
- return MEDIA_FILE_PREVIEW_PAGE;
- }
- return otherFilePreview.notSupportedFile(model, fileAttribute, "系统还不支持该格式文件的在线预览");
- }
- /**
- * 检查视频文件转换是否已开启,以及当前文件是否需要转换
- * @return
- */
- private boolean checkNeedConvert(boolean mediaTypes) {
- //1.检查开关是否开启
- if("true".equals(ConfigConstants.getMediaConvertDisable())){
- return mediaTypes;
- }
- return false;
- }
- private static String convertToMp4(String filePath,String outFilePath,String fileKey)throws Exception {
- FFmpegFrameGrabber frameGrabber = FFmpegFrameGrabber.createDefault(filePath);
- Frame captured_frame;
- FFmpegFrameRecorder recorder = null;
- try {
- File desFile=new File(outFilePath);
- //判断一下防止重复转换
- if(desFile.exists()){
- return outFilePath;
- }
- if (!ObjectUtils.isEmpty(fileKey)) { //判断 是压缩包的创建新的目录
- int index = outFilePath.lastIndexOf("/"); //截取最后一个斜杠的前面的内容
- String folder = outFilePath.substring(0, index);
- File path = new File(folder);
- //目录不存在 创建新的目录
- if (!path.exists()) {
- path.mkdirs();
- }
- }
- frameGrabber.start();
- recorder = new FFmpegFrameRecorder(outFilePath, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
- // recorder.setImageHeight(640);
- // recorder.setImageWidth(480);
- recorder.setFormat(mp4);
- recorder.setFrameRate(frameGrabber.getFrameRate());
- recorder.setSampleRate(frameGrabber.getSampleRate());
- //视频编码属性配置 H.264 H.265 MPEG
- recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
- //设置视频比特率,单位:b
- recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
- recorder.setAspectRatio(frameGrabber.getAspectRatio());
- // 设置音频通用编码格式
- recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
- //设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 128000 = 182kb)
- recorder.setAudioBitrate(frameGrabber.getAudioBitrate());
- recorder.setAudioOptions(frameGrabber.getAudioOptions());
- recorder.setAudioChannels(frameGrabber.getAudioChannels());
- recorder.start();
- while (true) {
- captured_frame = frameGrabber.grabFrame();
- if (captured_frame == null) {
- System.out.println("转码完成:"+filePath);
- break;
- }
- recorder.record(captured_frame);
- }
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }finally {
- if (recorder != null) { //关闭
- recorder.stop();
- recorder.close();
- }
- frameGrabber.stop();
- frameGrabber.close();
- }
- return outFilePath;
- }
- }
|