适用于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