如何使用Spring MVC返回视频,以便可以使用html5 <video>标记进行导航?

 端庄的一白_167 发布于 2023-02-09 19:47

如果我在Web服务器(Tomcat)中有一个文件并创建一个标签,我可以观看视频,暂停它,浏览它,并在完成后重新启动它.

但是如果我创建一个在请求时发送视频文件的REST接口,并将其URL添加到标签,我只能播放和暂停.没有倒带,没有快进,没有导航,没有.

那么,有没有办法解决这个问题?我在某处遗漏了什么吗?

视频文件与REST接口位于同一服务器中,REST接口仅检查会话并在找到应发送的视频后发送视频.

这些是我到目前为止尝试过的方法.它们都有效,但没有一个允许导航.

方法1,ResponseEntity:
/*
 * This will actually load the whole video file in a byte array in memory,
 * so it's not recommended.
 */
@RequestMapping(value = "/{id}/preview", method = RequestMethod.GET)
@ResponseBody public ResponseEntity getPreview1(@PathVariable("id") String id, HttpServletResponse response) {
    ResponseEntity result = null;
    try {
        String path = repositoryService.findVideoLocationById(id);
        Path path = Paths.get(pathString);
        byte[] image = Files.readAllBytes(path);

        response.setStatus(HttpStatus.OK.value());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentLength(image.length);
        result = new ResponseEntity(image, headers, HttpStatus.OK);
    } catch (java.nio.file.NoSuchFileException e) {
        response.setStatus(HttpStatus.NOT_FOUND.value());
    } catch (Exception e) {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
    return result;
}
方法2,流复制:
/*
 * IOUtils is available in Apache commons io
 */
@RequestMapping(value = "/{id}/preview2", method = RequestMethod.GET)
@ResponseBody public void getPreview2(@PathVariable("id") String id, HttpServletResponse response) {
    try {
        String path = repositoryService.findVideoLocationById(id);
        File file = new File(path)
        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());
    }
}
方法3,FileSystemResource:
@RequestMapping(value = "/{id}/preview3", method = RequestMethod.GET)
@ResponseBody public FileSystemResource getPreview3(@PathVariable("id") String id, HttpServletResponse response) {
    String path = repositoryService.findVideoLocationById(id);
    return new FileSystemResource(path);
}

bgraves.. 11

处理非静态资源的简单解决方案:

@SpringBootApplication
public class DemoApplication {

    private final static File MP4_FILE = new File("/home/ego/bbb_sunflower_1080p_60fps_normal.mp4");

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Controller
    final static class MyController {

        @Autowired
        private MyResourceHttpRequestHandler handler;

        // supports byte-range requests
        @GetMapping("/")
        public void home(
                HttpServletRequest request,
                HttpServletResponse response
        ) throws ServletException, IOException {

            request.setAttribute(MyResourceHttpRequestHandler.ATTR_FILE, MP4_FILE);
            handler.handleRequest(request, response);
        }

        // does not support byte-range requests
        @GetMapping(path = "/plain", produces = "video/mp4")
        public FileSystemResource plain() {

            return new FileSystemResource(MP4_FILE);
        }
    }

    @Component
    final static class MyResourceHttpRequestHandler extends ResourceHttpRequestHandler {

        private final static String ATTR_FILE = MyResourceHttpRequestHandler.class.getName() + ".file";

        @Override
        protected Resource getResource(HttpServletRequest request) throws IOException {

            final File file = (File) request.getAttribute(ATTR_FILE);
            return new FileSystemResource(file);
        }
    }
}

(灵感来自Spring Boots LogFileMvcEndpoint,或多或少等于Paul-Warrens(@ paul-warren)后来我发现的StoreByteRangeHttpRequestHandler).

希望这是Spring将在不久的将来支持的内容,请参阅https://jira.spring.io/browse/SPR-13834(请投票支持).

2 个回答
  • 处理非静态资源的简单解决方案:

    @SpringBootApplication
    public class DemoApplication {
    
        private final static File MP4_FILE = new File("/home/ego/bbb_sunflower_1080p_60fps_normal.mp4");
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
        @Controller
        final static class MyController {
    
            @Autowired
            private MyResourceHttpRequestHandler handler;
    
            // supports byte-range requests
            @GetMapping("/")
            public void home(
                    HttpServletRequest request,
                    HttpServletResponse response
            ) throws ServletException, IOException {
    
                request.setAttribute(MyResourceHttpRequestHandler.ATTR_FILE, MP4_FILE);
                handler.handleRequest(request, response);
            }
    
            // does not support byte-range requests
            @GetMapping(path = "/plain", produces = "video/mp4")
            public FileSystemResource plain() {
    
                return new FileSystemResource(MP4_FILE);
            }
        }
    
        @Component
        final static class MyResourceHttpRequestHandler extends ResourceHttpRequestHandler {
    
            private final static String ATTR_FILE = MyResourceHttpRequestHandler.class.getName() + ".file";
    
            @Override
            protected Resource getResource(HttpServletRequest request) throws IOException {
    
                final File file = (File) request.getAttribute(ATTR_FILE);
                return new FileSystemResource(file);
            }
        }
    }
    

    (灵感来自Spring Boots LogFileMvcEndpoint,或多或少等于Paul-Warrens(@ paul-warren)后来我发现的StoreByteRangeHttpRequestHandler).

    希望这是Spring将在不久的将来支持的内容,请参阅https://jira.spring.io/browse/SPR-13834(请投票支持).

    2023-02-09 19:49 回答
  • HTTP简历下载功能可能是您的朋友.我之前遇到过同样的问题.实施http范围后,视频中的导航是可能的:

    http://balusc.blogspot.com/2009/02/fileservlet-supporting-resume-and.html

    2023-02-09 19:50 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有