如何在视频 spring 启动时滚动?
How to scroll in video spring boot?
我在 spring 启动时构建了一个虚拟视频流应用程序,我注意到我无法跳到另一帧或视频中的特定时间。
这是我读取 videoFile
的代码
public byte[] getVideo() throws IOException {
byte[] bytes = new byte[(int) file.length()];
FileInputStream inputStream = new FileInputStream(file);
inputStream.read(bytes);
return bytes;
}
这是我的视频控制器returns
return ResponseEntity.status(HttpStatus.OK)
.header("Content-Type","video/mp4")
.header("Content-length",String.valueOf(streamingService.file.length()))
.body(streamingService.getVideo());
注意我没有使用任何前端
所以在一点点消除之后我发现它的原因是浏览器(chrome)对某个字节发出了另一个获取请求range.and我的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;
}
}
和我的控制器class代码
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 的建议,代码在两种浏览器上都运行良好
我在 spring 启动时构建了一个虚拟视频流应用程序,我注意到我无法跳到另一帧或视频中的特定时间。 这是我读取 videoFile
的代码public byte[] getVideo() throws IOException {
byte[] bytes = new byte[(int) file.length()];
FileInputStream inputStream = new FileInputStream(file);
inputStream.read(bytes);
return bytes;
}
这是我的视频控制器returns
return ResponseEntity.status(HttpStatus.OK)
.header("Content-Type","video/mp4")
.header("Content-length",String.valueOf(streamingService.file.length()))
.body(streamingService.getVideo());
注意我没有使用任何前端
所以在一点点消除之后我发现它的原因是浏览器(chrome)对某个字节发出了另一个获取请求range.and我的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;
}
}
和我的控制器class代码
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 的建议,代码在两种浏览器上都运行良好