视频就是一个快速连续播放的图片, 当每秒播放的速度足够快时,人眼就会觉得图片是“动”的(要求>24帧/秒)。随时间连续变换的多张画面中每张画面就叫一帧,如果把这些帧数据转换成图片文件并按顺序排列就是一个视频文件。如果把这个视频文件在网络上进行传输,那么数据必然就很大并且相邻的帧有需要重复的地方,所以有人就专门写了些算法对视频文件进行编码,常见的就是H.264编码,H.264编码将保留一张基本帧,其他的帧只是记录差别的地方。
在H.264编码中,得到的文件可以看做是连续的一组帧的集合,在这组帧当中,通常第一帧就是记录基本画面,是最重要的一帧数据,叫做I帧(Inter Frame),其他的帧数据是P帧(P-Frame)或B帧(B帧),P帧和B帧需要参考其他的帧数据才能还原画面。
所以获得I帧数据就可以进行播放了,从I帧数据开始到下个I帧数据之前所有的数据就一个GOP,即一个帧数据组。当我们看一个直播时通常会希望点开直播就能看到画面,即所谓的秒开,一般秒开的实现是拿到I帧就立马进行显示的。但是对于观看直播的用户来将进入直播间的时间是随机的,也许进来时刚好请求到I帧,立马可以拿到I帧, 也许进来时刚好I帧结束,那么他就需要等一个GOP时间之后才能拿到下组的I帧进行观看。这就产生了一个问题,GOP时间到底需要设置多长才合理?以及Gop的大小对直播到底有什么影响?
我们知道Gop时长就是指的2个I帧之间的时间差,一个Gop组中只有一个I帧。
如果Gop时间设置比较大时,显然B帧和P帧会有很多,则其对于的压缩比就比较高了,所耗费的流量就相对较小。但这样做的话,对于在I帧结束后进入直播间的用户来将就需要等待比较久的时间,等待时间就比较久了,达不到秒开的效果。
如果 GoP设置比较小时,由于GoP设置小可以降低I帧间隔时间,对于直播来说可以实现秒开的功能。但是由于GoP时间比较短,会导致I帧的比例增高,压缩比降低。同样码率情况下视频的质量会有所下降。数据流量也比较大了。
一般来讲Gop一般会设置为1-2秒比较合适。
上面讲到的秒开是针对客户端进行的一些设置, 对应服务器端也可以做些配置来实现秒开。在服务器端一般可以设置Gop缓存,即在服务器上保存上一个Gop组数据,当用户进入直播间时,立即拿到上一个Gop的I帧,这样客户端进入直播间的瞬间永远是I帧开头的数据,从而达到秒开。但是这种方案对于延迟要求比较高的场景不不适合了,毕竟拿到的是上一Gop的I帧,这就会增加了一个延迟,而且这个延迟和Gop大小有关。
所以如果要实时性的话,还是只能通过减少关键帧间隔来进行优化了。