代码调整
This commit is contained in:
@@ -143,7 +143,7 @@ public class FileStorageUtil {
|
|||||||
* @date 2023/3/7 23:04
|
* @date 2023/3/7 23:04
|
||||||
* @param filePath 文件在服务器的路径
|
* @param filePath 文件在服务器的路径
|
||||||
*/
|
*/
|
||||||
public void downloadStream(HttpServletResponse response, String filePath) throws IOException {
|
public void downloadStream(HttpServletResponse response, String filePath) {
|
||||||
InputStream inputStream;
|
InputStream inputStream;
|
||||||
OutputStream toClient = null;
|
OutputStream toClient = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,30 +1,36 @@
|
|||||||
package com.njcn.device.pq.controller;
|
package com.njcn.device.pq.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
import com.njcn.common.config.GeneralInfo;
|
||||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||||
import com.njcn.common.pojo.response.HttpResult;
|
import com.njcn.common.pojo.response.HttpResult;
|
||||||
import com.njcn.common.utils.HttpResultUtil;
|
import com.njcn.common.utils.HttpResultUtil;
|
||||||
import com.njcn.device.pq.pojo.param.LargeScreenParam;
|
import com.njcn.device.pq.mapper.ResourceMapper;
|
||||||
import com.njcn.device.pq.pojo.po.ResourceData;
|
import com.njcn.device.pq.pojo.po.ResourceData;
|
||||||
import com.njcn.device.pq.pojo.vo.MonitoringPointScaleVO;
|
|
||||||
import com.njcn.device.pq.service.LargeScreenService;
|
|
||||||
import com.njcn.device.pq.service.ResourceService;
|
import com.njcn.device.pq.service.ResourceService;
|
||||||
import com.njcn.system.pojo.po.Resinformation;
|
import com.njcn.oss.utils.FileStorageUtil;
|
||||||
import com.njcn.web.controller.BaseController;
|
import com.njcn.web.controller.BaseController;
|
||||||
|
import io.minio.GetObjectArgs;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import io.swagger.annotations.ApiParam;
|
import io.swagger.annotations.ApiParam;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +47,12 @@ public class ResourceController extends BaseController {
|
|||||||
|
|
||||||
private final ResourceService iResourceAdministrationService;
|
private final ResourceService iResourceAdministrationService;
|
||||||
|
|
||||||
|
private final ResourceMapper resourceMapper;
|
||||||
|
|
||||||
|
private final FileStorageUtil fileStorageUtil;
|
||||||
|
|
||||||
|
private final GeneralInfo generalInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传资源
|
* 上传资源
|
||||||
*/
|
*/
|
||||||
@@ -70,18 +82,140 @@ public class ResourceController extends BaseController {
|
|||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 预览资源
|
|
||||||
*/
|
|
||||||
//todo 未完成
|
|
||||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||||
@GetMapping("/previewFile")
|
@GetMapping("/play1")
|
||||||
@ApiOperation("预览资源")
|
@ApiOperation("播放视频资源")
|
||||||
@ApiImplicitParam(name = "id", value = "id", required = true)
|
@ApiImplicitParam(name = "id", value = "id", required = true)
|
||||||
public HttpResult<Object> previewFile(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void play1(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response) {
|
||||||
String methodDescribe = getMethodDescribe("downloadFile");
|
ResourceData resourceData = resourceMapper.selectById(id);
|
||||||
iResourceAdministrationService.previewFile(id, request, response);
|
fileStorageUtil.downloadStream(response,resourceData.getResUrl());
|
||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "成功", methodDescribe);
|
}
|
||||||
|
|
||||||
|
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||||
|
@GetMapping("/play2")
|
||||||
|
@ApiOperation("播放视频资源")
|
||||||
|
@ApiImplicitParam(name = "id", value = "id", required = true)
|
||||||
|
public void play2(@RequestParam("id") String id, HttpServletRequest request, HttpServletResponse response) {
|
||||||
|
RandomAccessFile targetFile = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
try {
|
||||||
|
outputStream = response.getOutputStream();
|
||||||
|
response.reset();
|
||||||
|
//获取请求头中Range的值
|
||||||
|
String rangeString = request.getHeader(HttpHeaders.RANGE);
|
||||||
|
//打开文件
|
||||||
|
File file = File.createTempFile(IdWorker.getIdStr(),".mp4");
|
||||||
|
ResourceData resourceData = resourceMapper.selectById(id);
|
||||||
|
InputStream ins = fileStorageUtil.getFileStream(resourceData.getResUrl());
|
||||||
|
long l = System.currentTimeMillis();
|
||||||
|
FileUtil.writeFromStream(ins,file);
|
||||||
|
long ll = System.currentTimeMillis();
|
||||||
|
System.out.println("流转文件耗时:"+(ll-l)+"=============================");
|
||||||
|
if (file.exists()) {
|
||||||
|
//使用RandomAccessFile读取文件
|
||||||
|
targetFile = new RandomAccessFile(file, "r");
|
||||||
|
long fileLength = targetFile.length();
|
||||||
|
long requestSize = (int) fileLength;
|
||||||
|
//分段下载视频
|
||||||
|
if (StringUtils.hasText(rangeString)) {
|
||||||
|
//从Range中提取需要获取数据的开始和结束位置
|
||||||
|
long requestStart = 0, requestEnd = 0;
|
||||||
|
String[] ranges = rangeString.split("=");
|
||||||
|
if (ranges.length > 1) {
|
||||||
|
String[] rangeDatas = ranges[1].split("-");
|
||||||
|
requestStart = Integer.parseInt(rangeDatas[0]);
|
||||||
|
if (rangeDatas.length > 1) {
|
||||||
|
requestEnd = Integer.parseInt(rangeDatas[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (requestEnd != 0 && requestEnd > requestStart) {
|
||||||
|
requestSize = requestEnd - requestStart + 1;
|
||||||
|
}
|
||||||
|
//根据协议设置请求头
|
||||||
|
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_TYPE, "video/mp4");
|
||||||
|
if (!StringUtils.hasText(rangeString)) {
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_LENGTH, fileLength + "");
|
||||||
|
} else {
|
||||||
|
long length;
|
||||||
|
if (requestEnd > 0) {
|
||||||
|
length = requestEnd - requestStart + 1;
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + requestEnd + "/" + fileLength);
|
||||||
|
} else {
|
||||||
|
length = fileLength - requestStart;
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + (fileLength - 1) + "/"
|
||||||
|
+ fileLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//断点传输下载视频返回206
|
||||||
|
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
||||||
|
//设置targetFile,从自定义位置开始读取数据
|
||||||
|
targetFile.seek(requestStart);
|
||||||
|
} else {
|
||||||
|
//如果Range为空则下载整个视频
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=demo.mp4");
|
||||||
|
//设置文件长度
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
//从磁盘读取数据流返回
|
||||||
|
byte[] cache = new byte[4096];
|
||||||
|
try {
|
||||||
|
while (requestSize > 0) {
|
||||||
|
int len = targetFile.read(cache);
|
||||||
|
if (requestSize < cache.length) {
|
||||||
|
outputStream.write(cache, 0, (int) requestSize);
|
||||||
|
} else {
|
||||||
|
outputStream.write(cache, 0, len);
|
||||||
|
if (len < cache.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestSize -= cache.length;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// tomcat原话。写操作IO异常几乎总是由于客户端主动关闭连接导致,所以直接吃掉异常打日志
|
||||||
|
//比如使用video播放视频时经常会发送Range为0- 的范围只是为了获取视频大小,之后就中断连接了
|
||||||
|
log.info(e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("文件路劲有误");
|
||||||
|
}
|
||||||
|
outputStream.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("文件传输错误", e);
|
||||||
|
throw new RuntimeException("文件传输错误");
|
||||||
|
}finally {
|
||||||
|
if(outputStream != null){
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("流释放错误", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(targetFile != null){
|
||||||
|
try {
|
||||||
|
targetFile.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("文件流释放错误", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static long getFileSize(InputStream inputStream) throws IOException {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int len;
|
||||||
|
long size = 0;
|
||||||
|
while ((len = inputStream.read(buffer)) != -1) {
|
||||||
|
size += len;
|
||||||
|
}
|
||||||
|
inputStream.close();
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user