minio 大视频观看,下载

在线观看

java 复制代码
 /**
     * 下载视频文件 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();
            }
        }
    }
相关推荐
yuanyxh8 分钟前
Mac 软件推荐
前端·javascript·程序员
万少13 分钟前
AtomCode开发微信小程序《谁去呀》 全流程
前端·javascript·后端
某人辛木28 分钟前
Web自动化测试
前端·python·pycharm·pytest
C+++Python1 小时前
详细介绍一下Java泛型的通配符
java·windows·python
Kagol1 小时前
Superpowers GSD gstack AgentSkills深度测评
前端·人工智能
JosieBook2 小时前
【数据库】时序预测能力的分级进化:TimechoAI如何让每一类用户都能精准预见未来
java·开发语言·数据库
excel2 小时前
JavaScript 字符串与模板字面量:从表象到本质理解
前端
京东云开发者2 小时前
当AI成为导演-如何用AI创作动漫短剧
前端
一生了无挂2 小时前
Java处理JSON技巧教学(从基础到高阶实战全覆盖)
java·开发语言·json
李白的天不白3 小时前
使用 SmartAdmin 进行前后端开发
java·前端