视频预览设置一次只下载3m大小
minio安装
Windows中Minio的安装和使用_minio登录地址-CSDN博客
minio JavaApi
代码参考
https://www.pudn.com/news/627cadde5981aa38ef847274.html
断点续传| ProcessOn免费在线作图,在线流程图,在线思维导图
最终实例(浏览器会根据range自动循环调用接口)
/**
* 视频断点续播预览
* @param bucketName
* @param fileName
* @param request
* @param res
*/
public void videoPreview(String bucketName,
String fileName,
HttpServletRequest request,
HttpServletResponse res) {
try {
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase(Locale.ROOT);
StatObjectResponse statObjectResponse = minioClient.statObject(
StatObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.build());
long fileSize = statObjectResponse.size();
final long bufferStep = 1024 * 1024 * 3; // 流区间
long startPos = 0; // 流起始位置
long endPos = fileSize - 1; // 流结束位置
String rangeHeader = request.getHeader("Range");
if (!ObjectUtils.isEmpty(rangeHeader) && rangeHeader.startsWith("bytes=")) {
try {
// 断点续传 状态码206
res.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
// 情景一:RANGE: bytes=2000070- 情景二:RANGE: bytes=2000070-2000970
String numRang = request.getHeader("Range").replaceAll("bytes=", "");
if (numRang.startsWith("-")) {
startPos = 0;
endPos = endPos - Long.parseLong(new String(numRang.getBytes(StandardCharsets.UTF_8), 1,
numRang.length() - 1));
} else if (numRang.endsWith("-")) {
startPos = Long.parseLong(new String(numRang.getBytes(StandardCharsets.UTF_8), 0,
numRang.length() - 1));
endPos = fileSize - 1;
} else {
String[] strRange = numRang.split("-");
if (strRange.length == 2) {
startPos = Long.parseLong(strRange[0].trim());
endPos = Long.parseLong(strRange[1].trim());
}
}
if (startPos < 0 || endPos < 0 || endPos >= fileSize || startPos > endPos) {
// range不满足
res.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return;
}
} catch (NumberFormatException e) {
LOGGER.error(request.getHeader("Range") + " is not Number!");
startPos = 0;
}
}
if (fileType.contains("MP4"))
res.setContentType("video/mp4");
else if (fileType.contains("AVI"))
res.setContentType("video/avi");
else if (fileType.contains("WEBM"))
res.setContentType("video/webm");
else if (fileType.contains("wmv"))
res.setContentType("video/x-ms-wmv");
else if (fileType.contains("mkv"))
res.setContentType("video/x-matroska");
if (endPos - startPos + 1 > bufferStep) {
endPos = startPos + bufferStep - 1; //设置为定长流区间
}
if (endPos >= fileSize)
endPos = fileSize - 1;
long resContentLength = bufferStep; // response内容长度
if (endPos == fileSize - 1)
resContentLength = endPos - startPos + 1; // 设置为文件剩余的实际长度
res.setHeader("Accept-Ranges", "bytes");
res.setHeader("Content-Range", String.format("bytes %d-%d/%d", startPos, endPos, fileSize));
res.addHeader("Content-Length", String.valueOf(resContentLength));
res.addHeader("Content-Type", "video/mp4");
GetObjectArgs objectArgs2 = GetObjectArgs.builder().bucket(bucketName)
.object(fileName)
.offset(startPos)
.length(bufferStep)
.build();
InputStream tmpStream = minioClient.getObject(objectArgs2);
ServletOutputStream stream = res.getOutputStream();
IOUtils.copy(tmpStream, stream);
stream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}