Chrome浏览器Video无法拖动的探索和解决方案

时间:2025-02-13 22:39:19

适用于MP4无法通过URL作为静态内容返回的场景。

环境:

1:spring boot

2:客户端 Chrome 浏览器

3:播放环境 Video原生标签

4:MP4物理路径无法无法直接请求到数据,需通过程序读取到内存然后返回。(如果这个MP4是静态内容,不需要程序处理,则一般不会有这个问题)

问题:无法进行拖放或者拖放以后要重头进行播放。

故障原因:与Video标签适配的请求未被响应。

如何做:

1:Chrome浏览器默认请求会在 Header 添加一个Range如下:服务器要做的就是响应这个Header

Range:             bytes=0-

2:服务器接收到这个Header以后,响应的Header如下,同时需要设置状态码为206

Accept-Ranges:     bytes
Content-Length:    2097152
Content-Range:     bytes 0-2097151/38696534

3:服务端代码实现

/**
     * 处理资源响应数据和响应头
     * @param request
     * @param response
     * @param data
     * @return
     */
    private byte[] handleResponseDataAndHeader(HttpServletRequest request, HttpServletResponse response, byte[] data) {
        String url = ().toString();
        String contentType = (url);
        if (!(contentType)) {
            (contentType);
        }
        ();
        // 缓存一天
        ("Cache-Control", "max-age=86400000");

        String rangeString = ("Range");
        if ((rangeString)) {
            return data;
        }
        return handleExistRangeResponseDataAndHeader(request, response, data);
    }

    /**
     * 处理请求头带range的资源响应数据和响应头
     * @param request
     * @param response
     * @param data
     * @return
     */
    private byte[] handleExistRangeResponseDataAndHeader(HttpServletRequest request,
                                                     HttpServletResponse response, byte[] data) {
        // 一次返回2M数据
        int onceDataLength = 2 * 1024 * 1024;
        String rangeString = ("Range");
        int[] rangeArray = getRangeArrayFromRangeString(rangeString, onceDataLength);
        if (rangeArray[1] > -1) {
            rangeArray[1] = -1;
        }
        ("Content-Range",
                "bytes " + rangeArray[0] + "-" + rangeArray[1] + "/" + );
        (HttpServletResponse.SC_PARTIAL_CONTENT);
        ("Accept-Ranges", "bytes");
        int byteLength = rangeArray[1] - rangeArray[0] + 1;
        (byteLength);
        byte[] onceData = new byte[byteLength];
        (data, rangeArray[0], onceData, 0, byteLength);
        return onceData;
    }

    /**
     * 获取请求需要的数据范围
     * @param rangeString
     * @param dataLength
     * @return
     */
    private int[] getRangeArrayFromRangeString(String rangeString, int dataLength) {
        int[] rangeArray = new int[2];
        rangeString = (("=") + 1);
        String rangeStartString = (0, ("-"));
        if ((())) {
            rangeArray[0] = (());
        } else {
            rangeArray[0] = 0;
        }

        if (("-") == ()-1) {
            rangeArray[1] = rangeArray[0] + dataLength - 1;
        } else {
            String rangeEndString = (("-") + 1);
            if ((())) {
                rangeArray[1] = (());
            } else {
                rangeArray[1] = rangeArray[0] + dataLength - 1;
            }
        }
        return rangeArray;
    }

参考原文链接:/hudaijun/article/details/87456583