【问题标题】:How to scroll in video spring boot?如何在视频弹簧靴中滚动?
【发布时间】:2021-08-05 07:06:12
【问题描述】:

我在 Spring Boot 中构建了一个虚拟视频流应用程序,我注意到我不能跳到另一个帧或视频中的某个时间。 这是我读取 videoFile 的代码

public byte[] getVideo() throws IOException {


        byte[] bytes = new byte[(int) file.length()];
        FileInputStream inputStream = new FileInputStream(file);
        inputStream.read(bytes);
        return bytes;
    }

这就是我的视频控制器返回的内容

return ResponseEntity.status(HttpStatus.OK)
                .header("Content-Type","video/mp4")
                .header("Content-length",String.valueOf(streamingService.file.length()))
                .body(streamingService.getVideo());

注意我没有使用任何前端

【问题讨论】:

  • 你没有添加headerAccept-Ranges: bytes,所以浏览器认为服务器不支持。

标签: java spring spring-boot video-streaming


【解决方案1】:

所以经过一点点清除后,我发现它的原因是浏览器(chrome)向某个字节范围发出了另一个 get 请求。我的 getVideo() 写得不好,无法接受字节范围并返回所需的字节范围。

重写我的 videoStreamingService 后,chrome 的问题已解决

这是我为 getVideo() 重写的代码

byte[] data;
        Long fileSize = file.length();
        String[] ranges = range.split("-");
        rangeStart = Long.parseLong(ranges[0].substring(6));
        if (ranges.length > 1) {
            rangeEnd = Long.parseLong(ranges[1]);
        } else {
            rangeEnd = fileSize - 1;
        }
        if (fileSize < rangeEnd) {
            rangeEnd = fileSize - 1;
        }
        contentLength = String.valueOf((rangeEnd - rangeStart) + 1);
       data = readByteRange( rangeStart, rangeEnd);
       return  data;

readRangeByte() 方法,以便我可以适当地读取数据

public byte[] readByteRange(long start, long end) throws IOException {
        try (InputStream inputStream = (Files.newInputStream(Path.of(videoFileName)));
             ByteArrayOutputStream bufferedOutputStream = new ByteArrayOutputStream()) {
            byte[] data = new byte[128];
            int nRead;
            while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                bufferedOutputStream.write(data, 0, nRead);
            }
            bufferedOutputStream.flush();
            byte[] result = new byte[(int) (end - start) + 1];
            System.arraycopy(bufferedOutputStream.toByteArray(), (int) start, result, 0, result.length);
            return result;
        }
    }

和我的控制器类代码

public  ResponseEntity<byte[]> video(@RequestHeader(value = "Range",required = false)String range) throws IOException {
        if (range == null) {
            return ResponseEntity.status(HttpStatus.OK)
                    .header("Content-Type", "video/mp4")
                    .header("Content-Length", String.valueOf(streamingService.file.length()))
                    .body(streamingService.readByteRange(streamingService.getRangeStart(),streamingService.file.length()-1));
        }
        byte[] data = streamingService.getVideo(range);

        return  ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
                .header("Content-Type", "video/mp4")
                .header("Accept-Ranges", "bytes")
                .header("Content-Length", streamingService.getContentLength())
                .header("Content-Range", "bytes" + " " + streamingService.getRangeStart() + "-" + streamingService.getRangeEnd() + "/" + streamingService.file.length())
                .body(data);

根据@Andreas 的建议,代码在两种浏览器上都运行良好

【讨论】:

  • range == null,也就是你第一次看视频的时候,不加headerAccept-Ranges: bytes,所以浏览器认为服务器不支持。
  • 哦,谢谢它现在可以与 firefox 一起使用,但它仍然在两个浏览器中缓冲几秒钟
猜你喜欢
  • 2018-09-13
  • 2021-01-18
  • 2017-12-22
  • 2018-02-14
  • 2019-05-03
  • 2021-04-20
  • 1970-01-01
  • 2023-01-07
  • 2018-10-03
相关资源
最近更新 更多