一、情况说明
手机端请求后端接口,返回视频流给前端,然后在手机端举行播放,手机端必要适配ios和安卓,后端在开辟好接口后在浏览器、postman调用接口时都能正常播放,安卓客户端也可以正常播放,但是ios播放失败。
刚开始觉得是网速太慢的原因,换了一个更小的视频,仍然不行,然后查了下资料,说是视频编码的问题,然后又换了下视频编码,仍然不行,最后颠末测试,发现ios客户端使用video标签分析视频时会根据相应的请求头举行读取数据,相应头必要包罗文件巨细,如果没有就无法分析视频,但是在安卓客户端和浏览器上是没有这种问题的,以是必要兼容ios。
二、条件说明
视频文件是通过手机拍摄,没有颠末任何处理的mp4文件。
后端是springboot项目,将视频放在resource资源目录下。
前端必要适配ios和安卓客户端,使用video标签举行分析。
三、后端代码
- 首先必要读取类路径下的指定资源文件,转换为二进制流,设置好相应头,再返回。
- import org.springframework.core.io.ClassPathResource;
- import org.springframework.util.FileCopyUtils;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URLEncoder;
- @GetMapping("/video/{fileName}")
- public void video2(@PathVariable String fileName, HttpServletResponse response) throws IOException {
- //读取类路径下的资源文件
- ClassPathResource resource = new ClassPathResource("file/" + fileName);
- //转为File对象
- File file = resource.getFile();
- //获取文件大小,因为file.length()返回的是long类型,单位是B,但是响应头是int类型,所以需要强转为int类型
- //int类型的大小为2147483647,折算下来,文件大小不能超过1GB,可以这样做,如果大小超过1GB,那么需要分段读取返回了
- int fileLength = (int)file.length();
- //将文件对象转为输入流
- FileInputStream input = new FileInputStream(file);
- //设置响应头,inline:表示在线预览,后面是文件的名字
- response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileName, "UTF-8"));
- //设置文件的大小 (ios不设置无法正常播放视频)
- response.setHeader("Content-Length", String.valueOf(fileLength));
- //文件格式
- response.setContentType("video/mp4");
- //将二进制流返回给前端
- FileCopyUtils.copy(input, response.getOutputStream());
- }
复制代码 四、总结
- 安卓和浏览器适配做得很好,只必要设置好文件类型和Content-Disposition,最后返回文件的二进制流即可。
但是ios客户端还必要设置文件巨细才能正确播放。
我只做了MP4格式的视频,其他格式的视频暂时还没有试过,百度看了下,其他视频文件大概会涉及到视频编码的问题。
- 在手机端上播放视频,流量很贵,像我的做法的话都是一次性返回整个文件的二进制流,如许过于暴力,后续优化的时候,大概要设置另外的相应头,举行分段返回。比如相应头中Content-Range是获取文件的部门内容。
- 用分段的形式返回文件二进制流的实现方式:分段返回文件二进制流的实现方式
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |