MediaFilePreviewImpl.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package cn.keking.service.impl;
  2. import cn.keking.config.ConfigConstants;
  3. import cn.keking.model.FileAttribute;
  4. import cn.keking.model.FileType;
  5. import cn.keking.model.ReturnResponse;
  6. import cn.keking.service.FilePreview;
  7. import cn.keking.utils.DownloadUtils;
  8. import cn.keking.service.FileHandlerService;
  9. import cn.keking.web.filter.BaseUrlFilter;
  10. import org.artofsolving.jodconverter.util.ConfigUtils;
  11. import org.bytedeco.ffmpeg.global.avcodec;
  12. import org.bytedeco.javacv.FFmpegFrameGrabber;
  13. import org.bytedeco.javacv.FFmpegFrameRecorder;
  14. import org.bytedeco.javacv.Frame;
  15. import org.springframework.stereotype.Service;
  16. import org.springframework.ui.Model;
  17. import java.io.File;
  18. /**
  19. * @author : kl
  20. * @authorboke : kailing.pub
  21. * @create : 2018-03-25 上午11:58
  22. * @description:
  23. **/
  24. @Service
  25. public class MediaFilePreviewImpl implements FilePreview {
  26. private final FileHandlerService fileHandlerService;
  27. private final OtherFilePreviewImpl otherFilePreview;
  28. private static Object LOCK=new Object();
  29. public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
  30. this.fileHandlerService = fileHandlerService;
  31. this.otherFilePreview = otherFilePreview;
  32. }
  33. @Override
  34. public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
  35. // 不是http开头,浏览器不能直接访问,需下载到本地
  36. if (url != null && !url.toLowerCase().startsWith("http")) {
  37. ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName());
  38. if (response.isFailure()) {
  39. return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
  40. } else {
  41. url=BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent());
  42. fileAttribute.setUrl(url);
  43. }
  44. }
  45. if(checkNeedConvert(fileAttribute.getSuffix())){
  46. url=convertUrl(fileAttribute);
  47. }else{
  48. //正常media类型
  49. String[] medias = ConfigConstants.getMedia();
  50. for(String media:medias){
  51. if(media.equals(fileAttribute.getSuffix())){
  52. model.addAttribute("mediaUrl", url);
  53. return MEDIA_FILE_PREVIEW_PAGE;
  54. }
  55. }
  56. return otherFilePreview.notSupportedFile(model, fileAttribute, "暂不支持");
  57. }
  58. model.addAttribute("mediaUrl", url);
  59. return MEDIA_FILE_PREVIEW_PAGE;
  60. }
  61. /**
  62. * 检查视频文件处理逻辑
  63. * 返回处理过后的url
  64. * @return url
  65. */
  66. private String convertUrl(FileAttribute fileAttribute) {
  67. String url = fileAttribute.getUrl();
  68. if(fileHandlerService.listConvertedMedias().containsKey(url)){
  69. url= fileHandlerService.getConvertedMedias(url);
  70. }else{
  71. if(!fileHandlerService.listConvertedMedias().containsKey(url)){
  72. synchronized(LOCK){
  73. if(!fileHandlerService.listConvertedMedias().containsKey(url)){
  74. String convertedUrl=convertToMp4(fileAttribute);
  75. //加入缓存
  76. fileHandlerService.addConvertedMedias(url,convertedUrl);
  77. url=convertedUrl;
  78. }
  79. }
  80. }
  81. }
  82. return url;
  83. }
  84. /**
  85. * 检查视频文件转换是否已开启,以及当前文件是否需要转换
  86. * @return
  87. */
  88. private boolean checkNeedConvert(String suffix) {
  89. //1.检查开关是否开启
  90. if("false".equals(ConfigConstants.getMediaConvertDisable())){
  91. return false;
  92. }
  93. //2.检查当前文件是否需要转换
  94. String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
  95. String type = suffix;
  96. for(String temp : mediaTypesConvert){
  97. if(type.equals(temp)){
  98. return true;
  99. }
  100. }
  101. return false;
  102. }
  103. /**
  104. * 将浏览器不兼容视频格式转换成MP4
  105. * @param fileAttribute
  106. * @return
  107. */
  108. private static String convertToMp4(FileAttribute fileAttribute) {
  109. //说明:这里做临时处理,取上传文件的目录
  110. String homePath = ConfigUtils.getHomePath();
  111. String filePath = homePath+File.separator+"file"+File.separator+"demo"+File.separator+fileAttribute.getName();
  112. String convertFileName=fileAttribute.getUrl().replace(fileAttribute.getSuffix(),"mp4");
  113. File file=new File(filePath);
  114. FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
  115. String fileName = null;
  116. Frame captured_frame = null;
  117. FFmpegFrameRecorder recorder = null;
  118. try {
  119. fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4");
  120. File desFile=new File(fileName);
  121. //判断一下防止穿透缓存
  122. if(desFile.exists()){
  123. return fileName;
  124. }
  125. frameGrabber.start();
  126. recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
  127. recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264  //AV_CODEC_ID_MPEG4
  128. recorder.setFormat("mp4");
  129. recorder.setFrameRate(frameGrabber.getFrameRate());
  130. //recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
  131. recorder.setSampleRate(frameGrabber.getSampleRate());
  132. recorder.setAudioChannels(frameGrabber.getAudioChannels());
  133. recorder.setFrameRate(frameGrabber.getFrameRate());
  134. recorder.start();
  135. while ((captured_frame = frameGrabber.grabFrame()) != null) {
  136. try {
  137. recorder.setTimestamp(frameGrabber.getTimestamp());
  138. recorder.record(captured_frame);
  139. } catch (Exception e) {
  140. }
  141. }
  142. recorder.stop();
  143. recorder.release();
  144. frameGrabber.stop();
  145. } catch (Exception e) {
  146. e.printStackTrace();
  147. }
  148. //是否删除源文件
  149. //file.delete();
  150. return convertFileName;
  151. }
  152. }