|
@@ -1,8 +1,13 @@
|
|
|
package org.jeecg.modules.system.controller;
|
|
|
|
|
|
import cn.hutool.cache.file.LFUFileCache;
|
|
|
+import cn.hutool.http.HtmlUtil;
|
|
|
+import cn.hutool.http.useragent.Browser;
|
|
|
+import cn.hutool.http.useragent.UserAgent;
|
|
|
+import cn.hutool.http.useragent.UserAgentParser;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.google.common.base.Strings;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.jeecg.common.api.vo.Result;
|
|
|
import org.jeecg.common.constant.CommonConstant;
|
|
@@ -27,10 +32,13 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
|
|
|
import org.springframework.web.servlet.HandlerMapping;
|
|
|
import org.springframework.web.servlet.ModelAndView;
|
|
|
|
|
|
+import javax.servlet.ServletOutputStream;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import java.io.*;
|
|
|
import java.net.URLDecoder;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
/**
|
|
|
* <p>
|
|
|
* 用户表 前端控制器
|
|
@@ -222,6 +230,8 @@ public class CommonController {
|
|
|
if(oConvertUtils.isEmpty(imgPath) || imgPath=="null"){
|
|
|
return;
|
|
|
}
|
|
|
+ String userAgent = request.getHeader("User-Agent");
|
|
|
+ UserAgent parse = UserAgentParser.parse(userAgent);
|
|
|
// 其余处理略
|
|
|
InputStream inputStream = null;
|
|
|
OutputStream outputStream = null;
|
|
@@ -245,6 +255,19 @@ public class CommonController {
|
|
|
//outputStream.write(cacheFile, 0, cacheFile.length);
|
|
|
inputStream = new ByteArrayInputStream(cacheFile);
|
|
|
log.info("视频缓存");
|
|
|
+ String browserName = parse.getBrowser().getName();
|
|
|
+ String osName = parse.getOs().getName();
|
|
|
+ if ((!Strings.isNullOrEmpty(browserName) && browserName.startsWith("Safari")) || (!Strings.isNullOrEmpty(osName) && osName.startsWith("iPhone"))) {
|
|
|
+ sendVideo(request, response, file, file.getName());
|
|
|
+ } else {
|
|
|
+ outputStream = response.getOutputStream();
|
|
|
+ byte[] buf = new byte[512000];
|
|
|
+ int len;
|
|
|
+ while ((len = inputStream.read(buf)) > 0) {
|
|
|
+ outputStream.write(buf, 0, len);
|
|
|
+ }
|
|
|
+ response.flushBuffer();
|
|
|
+ }
|
|
|
} else {
|
|
|
// 内存使用太多不使用缓存
|
|
|
/* LFUFileCache fileCache = sysFileCacheService.getFileCache(CACHE_IMG_NAME);
|
|
@@ -253,19 +276,17 @@ public class CommonController {
|
|
|
inputStream = new ByteArrayInputStream(fileBytes);
|
|
|
log.info("其他文件缓存");*/
|
|
|
inputStream = new BufferedInputStream(new FileInputStream(filePath));
|
|
|
+ outputStream = response.getOutputStream();
|
|
|
+ byte[] buf = new byte[4096];
|
|
|
+ int len;
|
|
|
+ while ((len = inputStream.read(buf)) > 0) {
|
|
|
+ outputStream.write(buf, 0, len);
|
|
|
+ }
|
|
|
+ response.flushBuffer();
|
|
|
}
|
|
|
- //inputStream = new BufferedInputStream(new FileInputStream(filePath));
|
|
|
- outputStream = response.getOutputStream();
|
|
|
- byte[] buf = new byte[4096];
|
|
|
- int len;
|
|
|
- while ((len = inputStream.read(buf)) > 0) {
|
|
|
- outputStream.write(buf, 0, len);
|
|
|
- }
|
|
|
- response.flushBuffer();
|
|
|
} catch (IOException e) {
|
|
|
log.error("预览文件失败" + e.getMessage());
|
|
|
response.setStatus(404);
|
|
|
- e.printStackTrace();
|
|
|
} finally {
|
|
|
if (inputStream != null) {
|
|
|
try {
|
|
@@ -285,6 +306,78 @@ public class CommonController {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ private void sendVideo(HttpServletRequest request, HttpServletResponse response, File file, String fileName) throws FileNotFoundException, IOException {
|
|
|
+ RandomAccessFile randomFile = new RandomAccessFile(file, "r");//只读模式
|
|
|
+ long contentLength = randomFile.length();
|
|
|
+ String range = request.getHeader("Range");
|
|
|
+ int start = 0, end = 0;
|
|
|
+ if(range != null && range.startsWith("bytes=")){
|
|
|
+ String[] values = range.split("=")[1].split("-");
|
|
|
+ start = Integer.parseInt(values[0]);
|
|
|
+ if(values.length > 1){
|
|
|
+ end = Integer.parseInt(values[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int requestSize = 0;
|
|
|
+ if(end != 0 && end > start){
|
|
|
+ requestSize = end - start + 1;
|
|
|
+ } else {
|
|
|
+ requestSize = Integer.MAX_VALUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ response.setContentType("video/mp4");
|
|
|
+ response.setHeader("Accept-Ranges", "bytes");
|
|
|
+ response.setHeader("ETag", fileName);
|
|
|
+ response.setHeader("Last-Modified", new Date().toString());
|
|
|
+ //第一次请求只返回content length来让客户端请求多次实际数据
|
|
|
+ if(range == null){
|
|
|
+ response.setHeader("Content-length", contentLength + "");
|
|
|
+ }else{
|
|
|
+ //以后的多次以断点续传的方式来返回视频数据
|
|
|
+ response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//206
|
|
|
+ long requestStart = 0, requestEnd = 0;
|
|
|
+ String[] ranges = range.split("=");
|
|
|
+ if(ranges.length > 1){
|
|
|
+ String[] rangeDatas = ranges[1].split("-");
|
|
|
+ requestStart = Integer.parseInt(rangeDatas[0]);
|
|
|
+ if(rangeDatas.length > 1){
|
|
|
+ requestEnd = Integer.parseInt(rangeDatas[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ long length = 0;
|
|
|
+ if(requestEnd > 0){
|
|
|
+ length = requestEnd - requestStart + 1;
|
|
|
+ response.setHeader("Content-length", "" + length);
|
|
|
+ response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
|
|
|
+ }else{
|
|
|
+ length = contentLength - requestStart;
|
|
|
+ response.setHeader("Content-length", "" + length);
|
|
|
+ response.setHeader("Content-Range", "bytes "+ requestStart + "-" + (contentLength - 1) + "/" + contentLength);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ServletOutputStream out = response.getOutputStream();
|
|
|
+ int needSize = requestSize;
|
|
|
+ randomFile.seek(start);
|
|
|
+ while(needSize > 0){
|
|
|
+ byte[] buffer = new byte[512000];
|
|
|
+ int len = randomFile.read(buffer);
|
|
|
+ if(needSize < buffer.length){
|
|
|
+ out.write(buffer, 0, needSize);
|
|
|
+ } else {
|
|
|
+ out.write(buffer, 0, len);
|
|
|
+ if(len < buffer.length){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ needSize -= buffer.length;
|
|
|
+ }
|
|
|
+ randomFile.close();
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
// /**
|
|
|
// * 下载文件
|
|
|
// * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|