http range播放mp4流程

实测chrome和safari等浏览器,常规浏览器在播放mp4等流媒体时,跟服务端的交互过程如下:

第一次请求

浏览器也不知道服务端是否支持range请求,所以它会发送一个普通的http请求以获取整个视频文件。服务端如果真的不支持range协议,那就正常返回整个视频文件,Content-Length就是整个视频文件的字节数,此时浏览器端的播放器是不支持播放点切换的。

如果服务端支持range协议,它会返回Accept-Ranges: bytes,bytes为 range的单位,这里为字节,同时返回 Content-Range: bytes start-end/total,向浏览器表明我真的支持range协议,其他处理跟上面类似,Content-Length: filesize,并返回整个视频文件。此时接收到返回的浏览器自身如果不支持range协议,也无所谓,直接接收视频全文件,下载完前也不能切换播放点。

当然现今的浏览器没有不支持range协议的,浏览器在接收到Accept-Ranges之后,发现:我去!可以换更好的协议呀!于是乎,会立马断开连接中止请求,这样服务端的视频全文件其实并没有返回给客户端。

所以第一次请求,其实是试探性地获知服务端是支持range协议的。

第二次请求

此时开始发送range请求,但浏览器还不太确信整个文件到底有多大,所以发送的是Range: 0-。服务端接收后,自然要补齐终点位置,返回的是: Content-Range: bytes 0-end/total,注意end=total-1,range里start和end都是字节的索引位置。这样Content-Length还是整个文件大小,于是乎,服务端还是开始准备返回整个视频文件,返回的状态也是200. 而浏览器一看,我天!真的支持!而且也确认了整个视频文件大小。接着,浏览器再立马断开连接,视频文件也并没有发送到浏览器,或者是部分发送到浏览器。

第三次请求

浏览器就开始老老实实走range协议了,不同浏览器行为有些许不同,chrome总是发送 Range: start-,start为上次接收到的位置,服务端每次都补齐end和total,返回206,表示Partial Content,浏览器端就开始同步播放视频,当接收到10多MB时,浏览器就重新发起新的Range: start-,如此反复。播放过程中,播放点可以随便切换,也会显示出整个视频的时长,浏览器会根据切换点,大体估算请求的位置,发起新的Range: start-格式请求。

关于播放位置切换

上面的讲解中有个问题,就是播放位置的切换是以时间轴为衡量的,而上面的range请求是以bytes字节为衡量的,两者当然并不是线性的。如果服务端有时间位置和字节位置的转换服务,那么就可以返回:Accept-Ranges: bytes, seconds,以告诉浏览器支持两种衡量单位。浏览器端请求的形式会变成Range: seconds=12-21,表示请求12秒到21秒的内容,而服务端返回为:Content-Range: seconds 11.85-21.16/3600,考虑视频是按帧存储的格式,并不能随便切,所以会告诉浏览器大概的切换位置(会包含请求的范围在内),以及整个视频为3600秒。

关于链接保护

如果必须走range协议,就可以在每个请求里判断链接是否过期,及时中止过期的视频链接。

其他

返回的header里,设置好Last-Modified, Expires, Cache-Control可以控制视频的缓存,减少重复请求。

发表于 2021年02月22日 17:29   评论:0   阅读:5637  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo