一、环境说明

  • JDK 1.8
  • Springboot 2.7.5
  • Minio 8.4.5
  • Vue3实现的微信公众号网页

二、问题描述

当前项目是基于springboot和vue3的前后端分离架构,前端目前主要是基于H5展示在微信公众号的网页中。在实现视频上传、在线播放时遇到问题:前端同事说苹果手机播放不了视频,刚开始是统一用的video标签,安卓可以正常播放,但是苹果手机就出现“视频播放失败”。前端同事尝试换过video.js、vue3-play、html5 api、avplay、mui-player,都无法解决该问题,于是开始尝试后端寻找解决方案。

三、后端解决思路

第一次,是尝试将视频请求的Content-Disposition由attachment;filename=**改成inline;filename=**,这样视频请求可以直接在浏览器播放,而不是下载。但是依旧没有解决苹果手机视频播放失败的问题。并尝试《iOS无法播放MP4视频文件的解决方案 mp4视频iphone播放不了怎么办》在nginx中加入“add_header Accept-Ranges bytes;”,未能解决该问题。

第二次,分析网上找的视频,将该视频嵌入video是可以在苹果手机播放的。通过观察该请求,发现是有206的响应码,开始研究断点下载,最终在《05.springboot使用minio实现分段下载》、《H5 Video播放视频iOS 断点下载处理》两篇文章的启发下,通过minio分段下载解决了该问题。

四、关键知识点

对于下载请求的响应需要包含以下几个特殊属性:

Accept-Ranges: bytes          接收字节请求
Content-Length: 2                 相应长度
Content-Range: bytes 0-1/18494715    bytes后面的空格不能少,0开始位置,1结束位置。“/”后面的是文件总大小长度

Content-Disposition     inline表示浏览器直接使用,attachment表示下载,fileName表示下载的文件名

HttpResponse

Status Code: 206 Partial Content      指示请求已成功并且主体包含所请求的数据范围

五、后端下载方法代码片段

public void downloadSlice(String bucketName, String filename, HttpServletResponse response,HttpServletRequest request) throws Exception{if (StringUtils.isNotBlank(filename)) {String range = request.getHeader("Range");//获取文件信息StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(filename).build());//开始下载位置long startByte = 0;//结束下载位置long endByte = statObjectResponse.size() - 1;//有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=-2343if (range.startsWith("-")) {endByte = Long.parseLong(ranges[0]);}//类型二:bytes=2343-else if (range.endsWith("-")) {startByte = Long.parseLong(ranges[0]);}}//类型三:bytes=22-2343else if (ranges.length == 2) {startByte = Long.parseLong(ranges[0]);endByte = Long.parseLong(ranges[1]);}} catch (NumberFormatException e) {startByte = 0;endByte = statObjectResponse.size() - 1;}}//要下载的长度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 = minioClient.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];int len;while ((len = stream.read(buffer)) != -1) {os.write(buffer, 0, len);}os.flush();os.close();response.flushBuffer();} catch (IOException e) {e.printStackTrace();}}}

Springboot+Minio通过分片下载解决IOS下H5无法播放视频问题相关推荐

  1. h5点播播放mp4视频遇到的坑,ios的h5不能播放视频等

    背景 h5的出现对多媒体在网页上的视频播放提供了支持,以前网页播放视频基本依赖于flash等插件.而h5的video标签实现了网页播放视频无插件化.因此,h5的出现给网页视频播放带来极大的便捷性,目前 ...

  2. uniapp H5页面嵌入微信小程序 ios 下 video组件 播放视频 设置 border-radius overflow:hidden 不生效

    在ios 系统中, 设置border-radius 可能会不生效(安卓有效),直接给要设置的元素设置 border-radius属性,再添加下面的代码即可实现功能: -webkit-backface- ...

  3. 解决IOS下window.open页面打不开问题

    解决IOS下window.open页面打不开问题 参考文章: (1)解决IOS下window.open页面打不开问题 (2)https://www.cnblogs.com/tangjiao/p/102 ...

  4. 解决iOS下拉回弹方法二

    原文地址:https://segmentfault.com/a/1190000007301527 一篇解决 iOS下拉回弹的文章分享给大家.加了些注释.并且应用在vue中.再次感谢原作者. <t ...

  5. h5 ios Safair下载文件自动添加.html导致文件乱码问题,ios不能使用接口播放视频的问题

    需求:h5 页面 下载pdf,doc,docx,xlsx,xls 文件的功能 在安卓手机和 ios上的uc浏览器是可以正常的 下载或者预览的 但是在ios的Safair 下载时会被自动添加html尾缀 ...

  6. 解决iOS微信H5支付跳转微信后不返回App问题(Swift-WKWebview)(转)

    解决iOS微信H5支付跳转微信后不返回App问题(Swift-WKWebview)(转) 参考文章: (1)解决iOS微信H5支付跳转微信后不返回App问题(Swift-WKWebview)(转) ( ...

  7. 解决Linux下chrome无法播放flash问题

    解决Linux下chrome无法播放flash问题 参考文章: (1)解决Linux下chrome无法播放flash问题 (2)https://www.cnblogs.com/plodsoft/p/5 ...

  8. 解决iphone 微信H5自动播放音乐问题

    解决iphone 微信H5自动播放音乐问题 参考文章: (1)解决iphone 微信H5自动播放音乐问题 (2)https://www.cnblogs.com/hlhs/p/11157401.html ...

  9. ubuntu18.04 下firefox 不能 播放视频,因为默认未安装FLASH插件。(当然只是原因之一)

    ubuntu18.04 下firefox 不能 播放视频,默认未安装FLASH插件 终端输入: sudo apt-get install flashplugin-nonfree

最新文章

  1. Android Studio导入Eclipse项目的两种方法
  2. VMware Workstation 更改语言
  3. windows中如何设置开机自启tomcat,nginx,jdk等应用服务的解决办法
  4. C 指针常量 和常量指针 指向常量的指针常量的使用
  5. Request_请求转发
  6. WebClient UI的Automatic Delta Handling是什么意思
  7. python中imread导入失败_ImportError:无法导入加载图像文件所需的Python Imaging Library(PIL)...
  8. Route Class
  9. 如何运用接口中的变量?接口可以扩展吗?
  10. 简单的BBcode parsing
  11. BP神经网络算法推导过程
  12. DPSK+PM调制解调
  13. TestCenter IGMP Proxy组播测试(bridge)
  14. 怎么把照片转换成jpg格式?jpg格式图片怎么弄
  15. 早上在玩支付宝的答答星球,认真点就有点赌徒心理了
  16. 服务器上如何查看日志记录
  17. img标签加载src图片,图片逆时针旋转了90度,解决方案
  18. 3D打印机硬件驱动-马林固件最新版本2.0.X中文注释(3)marlin 2.0.9.2 截至发稿时间2021年12月16日
  19. uni-icons中添加自定义图标
  20. c语言食堂消费管理系统,食堂消费管理系统_食堂财务管理系统v1.0单机版

热门文章

  1. Python之文章生成器
  2. Raspberry Pi 4b点亮树莓派桌面(官方烧录工具)
  3. 超级解压缩工具RAR Extractor The Unarchiver Pro
  4. Redis安装教程(详细)
  5. 第九城市CEO朱骏:一个人的掘金游戏
  6. 可怜的80后——最具牺牲精神的一代
  7. MFC中英文切换实现过程中遇到的问题
  8. 数据分析-建立回归模型的流程
  9. flex于java实现增删改查
  10. java unsafe park_在sun.misc.Unsafe.park(本机方法)中等待