如果传输状态为 206 部分内容,Chrome 将无法加载视频

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


final String path = StaticHandler.toPathSafe(httpExchange.getRequestURI().getPath());

System.out.println(path);

final File file = new File(path);


if (file.isFile())

{

    int code = 200;

    long position = 0L;

    long end = file.length();


    if (httpExchange.getRequestHeaders().containsKey("Range"))

    {

        try

        {

            long[] range = StaticHandler.parseRange(httpExchange.getRequestHeaders().get("Range").get(0));


            position = range[0];

            if (range[1] != -1)

                end = range[1];


            // the video loads fine when code = 200;

            code = 206;


            httpExchange.getResponseHeaders().set("Content-Range", "bytes " + position + "-" + end + "/" + file.length());

        }

        catch (Exception e)

        {

            e.printStackTrace();

        }

    }


    httpExchange.getResponseHeaders().set("Accept-Range", "bytes");

    httpExchange.getResponseHeaders().set("Content-Type", "video/mp4");

    httpExchange.getResponseHeaders().set("Content-Length", String.valueOf(end - position));


    System.out.println("Response: " + position + ", " + end);


    httpExchange.sendResponseHeaders(code, 0L);


    final FileChannel fileChannel = new FileInputStream(file).getChannel();

    final WritableByteChannel responseChannel = Channels.newChannel(response.getOutputStream());

    fileChannel.transferTo(position, end - position, responseChannel);


    responseChannel.close();

    fileChannel.close();

}

else

{

    System.out.println("404");

    httpExchange.sendResponseHeaders(404, -1);

}

上面的代码无法在 chrome 上加载,但在 firefox 中工作正常,这是我在 Chrome 中获得的标头:


Response Headers:


Accept-range: bytes

Content-length: 31491166

Content-range: bytes 0-31491166/31491166

Content-type: video/mp4

Date: Sat, 27 Jul 2019 14:32:55 GMT

Transfer-encoding: chunked


我是否遗漏了什么和/或我的代码有什么问题?


万千封印
浏览 785回答 2
2回答

杨魅力

范围包括开始到结束。不是起始长度例如:Content-range: bytes 0-0/31491166返回 1 个字节(从字节零到字节零)您的代码不起作用,因为浏览器正在等待一个从未发送过的字节。

噜噜哒

使用下面的代码片段。它在所有浏览器Safari、Firefox 和 Chrome上运行和测试。protected byte[] prepareContent(final HttpHeaders headers, byte[] media,&nbsp; &nbsp; &nbsp; &nbsp; String range) throws IOException {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; long rangeStart = 0;&nbsp; &nbsp; long rangeEnd;&nbsp; &nbsp; long fileSize = media.length;&nbsp; &nbsp; String[] ranges = range.split("-");&nbsp; &nbsp; rangeStart = Long.parseLong(ranges[0].substring(6));&nbsp; &nbsp; if (ranges.length > 1) {&nbsp; &nbsp; &nbsp; &nbsp; rangeEnd = Long.parseLong(ranges[1]);&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; rangeEnd = fileSize - 1;&nbsp; &nbsp; }&nbsp; &nbsp; if (fileSize < rangeEnd) {&nbsp; &nbsp; &nbsp; &nbsp; rangeEnd = fileSize - 1;&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; String contentLength = String.valueOf((rangeEnd - rangeStart) + 1);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; headers.add("Content-Length", contentLength);&nbsp; &nbsp; headers.add("Content-Range", "bytes " + rangeStart + "-" + rangeEnd + "/" + fileSize);&nbsp; &nbsp; headers.add("Content-Type", "video/mp4");&nbsp; &nbsp; headers.add("Accept-Ranges","bytes");&nbsp; &nbsp; return readByteRange(media, rangeStart, rangeEnd);}private byte[] readByteRange(byte[] media, long start, long end) throws IOException {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; try (InputStream inputStream = new ByteArrayInputStream(media);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ByteArrayOutputStream bufferedOutputStream = new ByteArrayOutputStream()) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; int nRead;&nbsp; &nbsp; &nbsp; &nbsp; while ((nRead = inputStream.read(media, 0, media.length)) != -1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bufferedOutputStream.write(media, 0, nRead);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; bufferedOutputStream.flush();&nbsp; &nbsp; &nbsp; &nbsp; byte[] result = new byte[(int) (end - start) + 1];&nbsp; &nbsp; &nbsp; &nbsp; System.arraycopy(bufferedOutputStream.toByteArray(), (int) start, result, 0, result.length);&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java