如何通过Spring Web服务器将HTTP视频流代理到任意数量的客户端

Ker*_*ker 7 java video spring video-streaming spring-boot

只要我在与Spring Webserver在同一网络上的服务器上播放视频HTTP流,例如在某些URL中,例如:

HTTP://本地主机:9090/httpstream

如何使用Spring将此视频流代理到任意数量的客户端?以下示例演示了所需的流程:

  1. Spring webserver可以在http:// localhost:9091/spring中找到
  2. 客户想要访问视频流,所以他将他的视频流播放器连接到http:// localhost:9091/spring(spring webserver)
  3. Spring WebServer应该将在http:// localhost:9090/httpstream上找到的流重定向到客户端,后者永远不会知道他访问了httpstream主机.连接由Spring完成,而不是由客户端完成

这是必需的,因为HTTPStream是一个不安全且未经过身份验证的主机,我想将它包装在一起Spring Webserver,以便我可以使用某种形式的安全性,例如Basic Auth.


我尝试过请求某种形式的映射,但是我找不到要返回的对象类型,也没有找到如何进行连接,但预期的行为应该是这样的:

@Controller
public class HttpStreamProxyController {

    @RequestMapping("/spring") {
    public /*Stream Object?*/ getSecuredHttpStream() {
       if (clientIsSecured) {
       //... Security information

       return   //What should be returned?
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

vso*_*oni 5

我不确定您使用哪种来源来生成视频流(实时摄像机或视频文件或 YouTube 视频或 ..)

您可能可以使用 StreamingResponseBody(需要 Spring 4.2+)。参考以下链接

http://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/streaming-response-body/

http://shazsterblog.blogspot.in/2016/02/asynchronous-streaming-request.html

尝试这个 -

    @GetMapping("/stream1")
        @ResponseBody
        public StreamingResponseBody getVidoeStream1(@RequestParam String any) throws IOException {
            /* do security check before connecting to stream hosting server */ 
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<Resource> responseEntity = restTemplate.exchange( "http://localhost:8080/stream", HttpMethod.GET, null, Resource.class );
            InputStream st = responseEntity.getBody().getInputStream();
            return (os) -> {
                readAndWrite(st, os);
            };


    }

private void readAndWrite(final InputStream is, OutputStream os)
            throws IOException {
        byte[] data = new byte[2048];
        int read = 0;
        while ((read = is.read(data)) > 0) {
            os.write(data, 0, read);
        }
        os.flush();
    }
Run Code Online (Sandbox Code Playgroud)

它应该工作。您可以根据自己的要求编写自己的 readAndWrite() 实现。

所以,你的 spring 代理控制器可能是这样的......

@Controller
public class HttpStreamProxyController {

    @RequestMapping("/spring") 
    @ResponseBody
    public StreamingResponseBody  getSecuredHttpStream() {
       if (clientIsSecured) {
       //... Security information

    RestTemplate restTemplate = new RestTemplate();
    // get video stream by connecting to stream hosting server  like this
            ResponseEntity<Resource> responseEntity = restTemplate.exchange( "https://ur-to-stream", HttpMethod.GET, null, Resource.class );
            InputStream st = responseEntity.getBody().getInputStream();
    // Or if there is any other preferred way of getting the video stream use that. The idea is to get the video input stream    

    // now return a StreamingResponseBody  object created by following lambda 
            return (os) -> {
                readAndWrite(st, os);
            };

       } else {
          return null;
       }

   }
}
Run Code Online (Sandbox Code Playgroud)

由您的休息端点返回的 StreamingResponseBody 将适用于 HTML5,这可能类似于 ..

<video width="320" height="240" controls>
  <source src="/spring" type="video/mp4">
  Your browser does not support the video tag
</video>
Run Code Online (Sandbox Code Playgroud)