视频的目录如下:
(1)新建类,加载视频资源
自定义一个类继承 ResourceHttpRequestHandler,重写 getResource() 方法获取文件资源,用
FileSystemResource 加载资源。
(2)Controller 层
@RestController@RequestMapping("/getVideo")@AllArgsConstructorpublic class FileRestController { @Autowired private NonStaticResourceHttpRequestHandler nonStaticResourceHttpRequestHandler; @GetMapping("/video") public void videoPreview(HttpServletRequest request, HttpServletResponse response) throws Exception { //sourcePath 是获取编译后 resources 文件夹的绝对地址,获得的原始 sourcePath 以/开头,所以要用 substring(1) 去掉第一个字符/ //realPath 即视频所在的完整地址 String sourcePath = this.getClass().getClassLoader().getResource("").getPath().substring(1); String realPath = sourcePath +"static/video/1.mp4"; Path filePath = Paths.get(realPath); if (Files.exists(filePath)) { // 利用 Files.probeContentType 获取文件类型 String mimeType = Files.probeContentType(filePath); if (!StringUtils.isEmpty(mimeType)) { // 设置 response response.setContentType(mimeType); } request.setAttribute(nonStaticResourceHttpRequestHandler.filepath, filePath); // 利用 ResourceHttpRequestHandler.handlerRequest() 实现返回视频流 nonStaticResourceHttpRequestHandler.handleRequest(request, response); } else { response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setCharacterEncoding(StandardCharsets.UTF_8.toString()); } }} 2、使用 I/O 流返回视频流(1)方式一
@RequestMapping(value = "redio")@Controllerpublic class RedioController { @RequestMapping(value = "/getVido", method = RequestMethod.GET) @ResponseBody public void getVido(HttpServletRequest request, HttpServletResponse response) { // 视频路径 String file = "E:/coding/IDEA_project/springbootdemo/target/classes/static/1.mp4"; try { //获得视频文件的输入流 FileInputStream inputStream = new FileInputStream(file); // 创建字节数组,数组大小为视频文件大小 byte[] data = new byte[inputStream.available()]; // 将视频文件读入到字节数组中 inputStream.read(data); String diskfilename = "final.mp4"; // 设置返回数据格式 response.setContentType("video/mp4"); response.setHeader("Content-Disposition", "attachment; filename="" + diskfilename + """); System.out.println("data.length " + data.length); response.setContentLength(data.length); response.setHeader("Content-Range", "" + Integer.valueOf(data.length - 1)); response.setHeader("Accept-Ranges", "bytes"); response.setHeader("Etag", "W/"9767057-1323779115364""); // 获得 response 的字节流 OutputStream os = response.getOutputStream(); // 将视频文件的字节数组写入 response 中 os.write(data); //先声明的流后关掉! os.flush(); os.close(); inputStream.close(); } catch (Exception e) { } } ServletOutputStream getOutputStream()获得字节流,通过该字节流的 write(byte[] bytes) 可以向 response 缓冲区中写入字节,再由 Tomcat 服务器将字节内容组成 Http 响应返回给浏览器。
如果要写字节,比如向浏览器传图片或者视频,就要靠 response.getOutputStream()。
(2)方式二
@RequestMapping(value = "/preview2", method = RequestMethod.GET)@ResponseBody public void getPreview2( HttpServletResponse response) { try { File file = new File("E:/coding/IDEA_project/springbootdemo/target/classes/static/1.mp4"); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setHeader("Content-Disposition", "attachment; filename="+file.getName().replace(" ", "_")); InputStream iStream = new FileInputStream(file); IOUtils.copy(iStream, response.getOutputStream()); response.flushBuffer(); } catch (java.nio.file.NoSuchFileException e) { response.setStatus(HttpStatus.NOT_FOUND.value()); } catch (Exception e) { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); } } 二、后端 url 播放视频可以通过访问后端url进行视频播放了
测试:http://localhost:1111/getVideo/video