java 如何在视频中滚动Spring Boot ?

qaxu7uf2  于 2023-01-29  发布在  Java
关注(0)|答案(1)|浏览(90)

我在Sping Boot 中构建了一个虚拟的视频流应用程序,我注意到我不能跳到另一帧或视频中的某个时间。

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());

注意我没有使用任何前端

wwtsj6pe

wwtsj6pe1#

因此,经过一些实验,我发现浏览器(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的建议下,代码在两种浏览器上都运行得很好

相关问题