Java 如果使用状态206部分内容传输,Chrome无法加载视频

Java 如果使用状态206部分内容传输,Chrome无法加载视频,java,google-chrome,video-streaming,html5-video,httpserver,Java,Google Chrome,Video Streaming,Html5 Video,Httpserver,我正在制作一个简单的Javacom.sun.net.httpserver.httpserver来提供静态视频文件。如果我返回状态代码206,部分内容,当我尝试通过浏览器访问时,视频无法播放(视频播放状态代码为200,但我希望能够查找并循环视频),这是我的HttpHandler: final String path=StaticHandler.toPathSafe(httpExchange.getRequestURI().getPath()); System.out.println(路径); 最终

我正在制作一个简单的Java
com.sun.net.httpserver.httpserver
来提供静态视频文件。如果我返回状态代码206,部分内容,当我尝试通过浏览器访问时,视频无法播放(视频播放状态代码为200,但我希望能够查找并循环视频),这是我的
HttpHandler

final String path=StaticHandler.toPathSafe(httpExchange.getRequestURI().getPath());
System.out.println(路径);
最终文件=新文件(路径);
if(file.isFile())
{
int代码=200;
长位置=0升;
long end=file.length();
if(httpExchange.getRequestHeaders().containsKey(“范围”))
{
尝试
{
long[]range=StaticHandler.parseRange(httpExchange.getRequestHeaders().get(“range”).get(0));
位置=范围[0];
如果(范围[1]!=-1)
结束=范围[1];
//当代码=200时,视频加载良好;
代码=206;
httpExchange.getResponseHeaders().set(“内容范围”,“字节数”+位置+“-”+结束+“/”+文件长度());
}
捕获(例外e)
{
e、 printStackTrace();
}
}
httpExchange.getResponseHeaders().set(“接受范围”、“字节”);
httpExchange.getResponseHeaders().set(“内容类型”、“视频/mp4”);
httpExchange.getResponseHeaders().set(“内容长度”,String.valueOf(end-position));
System.out.println(“响应:“+position+”,“+end”);
httpExchange.SendResponseHeader(代码,0L);
final FileChannel FileChannel=新文件输入流(file).getChannel();
final WritableByteChannel responseChannel=Channels.newChannel(response.getOutputStream());
传输到(位置、结束位置、响应通道);
responseChannel.close();
fileChannel.close();
}
其他的
{
系统输出打印项次(“404”);
httpExchange.sendsresponseheaders(404,-1);
}
上面的代码无法在chrome上加载,但在firefox中运行良好,以下是我在chrome中获得的标题:

响应头:
接受范围:字节
内容长度:31491166
内容范围:字节0-31491166/31491166
内容类型:视频/mp4
日期:2019年7月27日星期六14:32:55 GMT
传输编码:分块
请求标头:
接受:*/*
接受编码:身份;q=1,*;q=0
接受语言:en-US,en;q=0.9
缓存控制:没有缓存
连接:保持活力
主持人:192.168.56.1:5000
Pragma:没有缓存
范围:字节=0-
推荐人:http://192.168.56.1:5000/30MB.mp4
用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/75.0.3770.142 Safari/537.36

我是否遗漏了某些内容和/或我的代码中存在错误?

范围包括起始和结束。非起始长度

例如:

内容范围:字节0-0/31491166

返回1字节(从零字节到零字节)


您的代码无法工作,因为浏览器正在等待一个从未发送的字节

使用下面的代码段。它可以在所有浏览器Safari、Firefox和Chrome上运行和测试

protected byte[] prepareContent(final HttpHeaders headers, byte[] media,
        String range) throws IOException {
    
    long rangeStart = 0;
    long rangeEnd;

    long fileSize = media.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;
    }
    
    String contentLength = String.valueOf((rangeEnd - rangeStart) + 1);
    
    headers.add("Content-Length", contentLength);
    headers.add("Content-Range", "bytes " + rangeStart + "-" + rangeEnd + "/" + fileSize);
    headers.add("Content-Type", "video/mp4");
    headers.add("Accept-Ranges","bytes");
    return readByteRange(media, rangeStart, rangeEnd);
}

private byte[] readByteRange(byte[] media, long start, long end) throws IOException {
    
    try (InputStream inputStream = new ByteArrayInputStream(media);
         ByteArrayOutputStream bufferedOutputStream = new ByteArrayOutputStream()) {
        
        int nRead;
        while ((nRead = inputStream.read(media, 0, media.length)) != -1) {
            bufferedOutputStream.write(media, 0, nRead);
        }
        bufferedOutputStream.flush();
        byte[] result = new byte[(int) (end - start) + 1];
        System.arraycopy(bufferedOutputStream.toByteArray(), (int) start, result, 0, result.length);
        return result;
    }
}
protectedbyte[]prepareContent(最终HttpHeaders、byte[]媒体、,
字符串范围)引发IOException{
长范围启动=0;
远程终端;
long fileSize=media.length;
String[]ranges=range.split(“-”);
rangeStart=Long.parseLong(范围[0]。子字符串(6));
如果(ranges.length>1){
rangeEnd=Long.parseLong(范围[1]);
}否则{
rangeEnd=fileSize-1;
}
如果(文件大小<范围结束){
rangeEnd=fileSize-1;
}
字符串contentLength=String.valueOf((rangeEnd-rangeStart)+1);
标题。添加(“内容长度”,contentLength);
添加(“内容范围”、“字节数”+rangeStart+“-”+rangeEnd+“/”+文件大小);
添加(“内容类型”、“视频/mp4”);
添加(“接受范围”、“字节”);
返回readByteRange(介质、范围开始、范围结束);
}
专用字节[]readByteRange(字节[]媒体,长起始,长结束)引发IOException{
try(InputStream-InputStream=newbytearrayinputstream(媒体);
ByteArrayOutputStream bufferedOutputStream=新建ByteArrayOutputStream()){
国际nRead;
while((nRead=inputStream.read(media,0,media.length))!=-1){
bufferedOutputStream.write(媒体,0,nRead);
}
bufferedOutputStream.flush();
字节[]结果=新字节[(int)(结束-开始)+1];
System.arraycopy(bufferedOutputStream.toByteArray(),(int)start,result,0,result.length);
返回结果;
}
}

例如,如果我想要视频的第一兆字节,我会发送一个范围为
bytes=0-1023的请求