用了eggjs,后台完全是RESTful api。播放视频时根本不能快进,一快进视频就停止了。只能重新播放。
http头Content-Rang也设置了的。
在浏览器输入http://127.0.0.1:7001/api/resources/9.mp4
下图是播放的视频
但是这个视频它只能播放3秒,播放3秒之后就卡住了,我打开了chrome控制台查看网络请求。
-
这是第一次请求的图片截图: (图1) 可以看到在Request Headers中并没有
Range:bytes 0-
字段。因为我在后端代码中判断前台发送的http请求头中是否有 range,如果没有的话我在响应头中设置以下默认值:let header = { 'Accept-Ranges': 'bytes', 'Content-Type': type, 'Content-Length': 视频文件的大小, 'Content-Range': `bytes 0-视频文件的大小/视频文件的大小`, "cache-control":'public,max-age=31536000' };
在(图1)中的Response Headers中可以看到以上默认字段 这时后端控制台打印如下图: (图1.1) 2.这是第二次请求的图片截图 (图2)
Response Headers中的值并没有变,但是Request Headers中出现了
Range: bytes=0-
字段 后端打印和(图1.1)一样,但是时间戳多了一秒,如下图: 图(2.1) 3.这是第三次请求的图片截图 (图3)以下是疑问: 1. Request Headers中
Range: bytes=23035904-
"23035904"数字怎么来的 后台打印的如下图: (图3.1) 最后后台也没有打印,视频在这3次请求中一直在播放,只放了3秒,视频就终止了。
然后我又打开了一个窗口,在浏览器输入http://127.0.0.1:7001/api/resources/9.mp4
后台打印如下图
(图4)
视频一直在播放,下图是控制台请求的图片
(图4.1)
上图中138Mb部分一直在增加
请求头和响应头如下图
(图4.2)
现在我来把视频进度条往后拉,前端后端状态如下(图4.3)(图4.4):
(图4.3)
(图4.4)
这时视频停止播放了,后台也没有打印数据了。
以下是后端代码代码。
//type "video/mp4"
video(filePath, type) {
const { ctx, app } = this;
if (!(/video/.test(type))) {
return;
}
let fileSize = fs.statSync(filePath).size;
let step=parseInt(fileSize/100);
let start = ctx.get('range').substr(ctx.get('range').indexOf('=') + 1, ctx.get('range').indexOf('-') - 1),
end = ctx.get('range').substr(ctx.get('range').indexOf('-') + 1);
start = parseInt(start);
end = parseInt(end);
if (isNaN(start)) {
start=0;
}
if (isNaN(end)) {
end = fileSize - 1;
// end=start+step>=fileSize?fileSize-1:start+step;
}
console.log('**************************')
console.log('start-end', start,'-',end)
console.log('**************************')
ctx.status = 206;
let header = {
'Accept-Ranges': 'bytes',
'Content-Type': type,
'Content-Length': end - start + 1,
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
"cache-control":'public,max-age=31536000'
};
ctx.set(header);
ctx.body = fs.createReadStream(filePath, {
satrt: start,
end: end,
autoClose:true
});
}
现在我去B站随便找一个视频看他的网络状况,我随机往后点击进度条
Request Headers
中第一次出现range
的请求如下图
我不知道为什么Range: bytes=1008-1735
初始bytes不是0而是1008
前台显示如下系列图(部分):
三次请求中
一.Request Headers
中的 range
分为三段连续的
->1.Range: bytes=12265533-12871199
->2.Range: bytes=12871200-13386314
->3.Range: bytes=13386315-13922958
二.Response Headers
中的 Content-Range
同理也分为三段连续的
->1.Content-Range: bytes=12265533-12871199/33430066
->2.Content-Range: bytes=12871200-13386314/33430066
->3.Content-Range: bytes=13386315-13922958/33430066
这样的实现了向后快进播放。
1.为啥我的就不可以快进,
2.为啥我的Range
直接是Range: bytes=0-视频文件大小
,并没没有分块,但我们的Status Code:都是206
这个错误 ERROR 112264 [-/127.0.0.1/-/21ms GET /api/resources/9.mp4] nodejs.ECONNABORTEDError: write ECONNABORTED到底是什么鬼
start not strat
@MiYogurt 什么意思?兄弟你知道这个问题该怎么解决吗
fs.createReadStream(filePath, {
start: <number>start,
end: end,
autoClose: false
})
@MiYogurt 谢谢老哥指正,虽然现在可以快进了,但是要是点击进度条的跨度太大的话,也会终止.后台也没有任何打印。 还有就是B站的加载视频是一个块一个块加载的,他是怎么搞的啊
config.onerror = {
appErrorFilter(err, ctx) {
const errnoCodeWhitelist = ['EPIPE'];
if (errnoCodeWhitelist.includes(err.errno)) {
return false
}
return true
},
};
不是终止,是继续去拉取,我测试的都是 20mb 左右的,我这里都可以正常播放。 块加载跟播放器有关,没研究过。
B站用的是http-flv了解下 自豪地采用 CNodeJS ionic
@MiYogurt 谢谢了
@bendise ok