在线观看
/**
* 下载视频文件 fileName文件路径名称 文件路径 BacketName/video/1111.mp4 需要截取桶名后面的路径 video/1111.mp4 video前面不要带/
*
* @param fileName
* @param request
* @param response
*/
public void play(String fileName, HttpServletRequest request, HttpServletResponse response) {
if (StringUtils.isNotBlank(fileName)) {
log.info("download:" + fileName);
String range = request.getHeader("Range");
log.info("current request rang:" + range);
//获取文件信息
// 调用statObject()来判断对象是否存在。
// 如果不存在, statObject()抛出异常,
// 否则则代表对象存在。
StatObjectResponse statObjectResponse = null;
try {
statObjectResponse = client.statObject(
StatObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName).build());
} catch (ErrorResponseException e1) {
e1.printStackTrace();
} catch (InsufficientDataException e1) {
e1.printStackTrace();
} catch (InternalException e1) {
e1.printStackTrace();
} catch (InvalidKeyException e1) {
e1.printStackTrace();
} catch (InvalidResponseException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (ServerException e1) {
e1.printStackTrace();
} catch (XmlParserException e1) {
e1.printStackTrace();
}
System.out.println(statObjectResponse);
//开始下载位置
long startByte = 0;
//结束下载位置
long endByte = statObjectResponse.size() - 1;
log.info("文件开始位置:{},文件结束位置:{},文件总长度:{}", startByte, endByte, statObjectResponse.size());
//有range的话
if (StringUtils.isNotBlank(range) && range.contains("bytes=") && range.contains("-")) {
range = range.substring(range.lastIndexOf("=") + 1).trim();
String[] ranges = range.split("-");
try {
//判断range的类型
if (ranges.length == 1) {
//类型一:bytes=-2343
if (range.startsWith("-")) {
endByte = Long.parseLong(ranges[0]);
}
//类型二:bytes=2343-
else if (range.endsWith("-")) {
startByte = Long.parseLong(ranges[0]);
}
}
//类型三:bytes=22-2343
else if (ranges.length == 2) {
startByte = Long.parseLong(ranges[0]);
endByte = Long.parseLong(ranges[1]);
}
} catch (NumberFormatException e) {
startByte = 0;
endByte = statObjectResponse.size() - 1;
log.error("Range Occur Error, Message:" + e.getLocalizedMessage());
}
}
//要下载的长度
long contentLength = endByte - startByte + 1;
//文件类型
String contentType = request.getServletContext().getMimeType(fileName);
//解决下载文件时文件名乱码问题
byte[] fileNameBytes = fileName.getBytes(StandardCharsets.UTF_8);
fileName = new String(fileNameBytes, 0, fileNameBytes.length, StandardCharsets.ISO_8859_1);
//各种响应头设置
//支持断点续传,获取部分字节内容:
response.setHeader("Accept-Ranges", "bytes");
//http状态码要为206:表示获取部分内容
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
response.setContentType(contentType);
response.setHeader("Last-Modified", statObjectResponse.lastModified().toString());
//inline表示浏览器直接使用,attachment表示下载,fileName表示下载的文件名
response.setHeader("Content-Disposition", "inline;filename=" + fileName);
response.setHeader("Content-Length", String.valueOf(contentLength));
//Content-Range,格式为:[要下载的开始位置]-[结束位置]/[文件总大小]
response.setHeader("Content-Range", "bytes " + startByte + "-" + endByte + "/" + statObjectResponse.size());
response.setHeader("ETag", "\"".concat(statObjectResponse.etag()).concat("\""));
try {
GetObjectResponse stream = client.getObject(
GetObjectArgs.builder()
.bucket(statObjectResponse.bucket())
.object(statObjectResponse.object())
.offset(startByte)
.length(contentLength)
.build());
BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[1024*40];
int len;
while ((len = stream.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
os.flush();
os.close();
response.flushBuffer();
log.info("下载完毕");
} catch (ClientAbortException e) {
log.warn("用户停止下载:" + startByte + "-" + endByte);
//捕获此异常表示拥护停止下载
} catch (IOException e) {
e.printStackTrace();
log.error("用户下载IO异常,Message:{}", e.getLocalizedMessage());
} catch (XmlParserException e1) {
e1.printStackTrace();
} catch (ServerException e1) {
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (InsufficientDataException e1) {
e1.printStackTrace();
} catch (InvalidKeyException e1) {
e1.printStackTrace();
} catch (InvalidResponseException e1) {
e1.printStackTrace();
} catch (ErrorResponseException e1) {
e1.printStackTrace();
} catch (InternalException e1) {
e1.printStackTrace();
}
}
}