使用 Spring boot 作为代理从 URL 流式传输视频

问题描述 投票:0回答:1

我需要创建一个流视频的端点。要流式传输的视频来自 Home Assistant 摄像头,采用 HLS 格式。

我尝试了不同的技术,但我无法在浏览器中本地观看视频流,甚至无法使用 html 播放器观看视频流。我看到数据正在传输,我只是不确定它是否是正确的数据。

这是我到目前为止所拥有的:

  1. @服务
    @Override
    public StreamingResponseBody streamVideo(String cameraId) throws Exception {
        String url = "http://localhost:8123/api/camera_proxy_stream/camera.back_patio_sub?token=c88e0f18d35004dd9051e477d3c4125894d2fc5db7b820450892d236cd65a603";

        log.info("Streaming from: {}", url);
        return outputStream -> {
            try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
                HttpGet request = new HttpGet(url);
                try (CloseableHttpResponse response = httpClient.execute(request)) {
                    HttpEntity entity = response.getEntity();

                    if (entity != null) {
                        try (InputStream inputStream = entity.getContent()) {
                            byte[] buffer = new byte[8192];
                            int bytesRead;
                            while ((bytesRead = inputStream.read(buffer)) != -1) {
                                outputStream.write(buffer, 0, bytesRead);
                            }
                        }
                    }
                    
                }
            }
        };
    }
  1. @RestController
    @GetMapping(value = "/stream/{cameraId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<StreamingResponseBody> streamVideo(@PathVariable String cameraId) throws Exception {
        
        try {
            StreamingResponseBody stream = cameraLiveService.streamVideo(cameraId);
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                    .header(CONTENT_LENGTH, DEFAULT_CONTENT_LENGHT)
                    .header(PRAGMA, NO_CACHE)
                    .header(CACHE_CONTROL, NO_CACHE)
                    .body(stream);
        } catch (AsyncRequestTimeoutException ex) {
            //Configurable value for timeout in application.properties:spring.mvc.async.request-timeout
            log.error("Timeout streaming video from camera: {}", cameraId, ex);
            throw new StreamRequestTimeoutException("Timeout streaming video from camera: " + cameraId, ex);
        } 
    }

如果我将 Home Assistant URL 粘贴到浏览器中,它就会开始播放,没有任何问题,但当我尝试代理它时,我无法实现它。

出于安全原因需要代理,以使用存储的 Home Assistant 长期令牌,但这是唯一的原因。

我也尝试过使用 RestTemplate,但似乎数据没有被传输,CloseableHttpClient 是我所看到的实际做的事情。

此外,“流式传输”数据时似乎不会抛出任何异常。

我在这里缺少什么?

spring-boot camera video-streaming home-assistant
1个回答
0
投票

我找到了解决方案。由于我能够看到字节到来,我知道问题出在响应本身,因此我决定保留 Home Assistant(原始提要)中的标头并删除我正在设置的标头。

Header[] headers = response.getAllHeaders();

//Keep the headers from the response.
for (Header header : headers) {
   response.setHeader(header.getName(), header.getValue());
}
© www.soinside.com 2019 - 2024. All rights reserved.