一、准备知识:

先了解下直播的播放原理

(1)首先拿到一个在线播放地址,例如:http://xxx:8080/live/161347.stream/playlist.m3u8?ext=m3u8

(2)然后把播放地址扔给播放器

(3)播放器通过地址拿到m3u8文件 如下,没有结束标识,因为直播一直在持续更新,点播是有结束标识的。

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:16424144
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:8
#EXTINF:7.680000,
16424149.ts
#EXTINF:7.680000,
16424150.ts
#EXTINF:5.120000,
16424151.ts
#EXTINF:5.120000,
16424152.ts
#EXTINF:7.680000,
16424153.ts

 

(4)去缓存倒数第二个16424152.ts 和倒数第一个分片16424153.ts,缓存完成后开始播放16424152.ts(这样保证有一个分片的缓存,尽量避免卡顿),每播放完成一个分片就再去请求更新一次m3u8文件,持续去预缓存下一个分片。

       注意:这里有可能去缓存2个、3个分片 这是播放器内部的行为。

二、时移方案一,后台录制直播内容,生成时移播放的m3u8文件,用户请求时动态刷新这个m3u8文件

(1)直播中拖动进度条、或者机顶盒上按快退键进入时移,播放器根据用户时移的长度去后台请求时移播放的m3u8文件

(2)和直播一样缓存后两个分片,然后去播放倒数第二个分片,每播放完成一个分片就再去请求更新一次m3u8文件

(3)用户快进或者快退时再次去请求m3u8文件,每次seek都请求 当然要带着时移的长度 --- offset (应用上层根据用户拖动或按快进快退操作去维护这个值)

        具体操作可以在直播的url上拼接上offset 然后把新的url设置给播放器去播放,后台配合解析这个offset返回m3u8

        例如:http://xxx:8080/live/161347.stream/playlist.m3u8?ext=m3u8&offset=1000,这个url每次seek 都要重新设置,offset在变

优点:m3u8文件小,http请求时body就小了,后台也不用维护一个很大的m3u8文件,不用定时刷新它

缺点:每次seek都请求m3u8文件,产生大量请求,用户体验不流畅

三、时移方案二,后台录制直播内容,生成时移播放的m3u8文件,类似直播一样不断刷新这个m3u8文件,单独提供一个时移的播放地址timeshiftUrl,这个m3u8会比较大,例如需求是支持2小时的时移,那这个文件可能会有几K的大小,2小时的ts文件信息都在里面

(1)直播中拖动进度条、或者机顶盒上按快退键进入时移,播放器播放这个timeshiftUrl,然后根据用户时移的长度去seek到指定分片(根据offset、每个分片的长度,序号可以实现),这个需要自定义播放器实现,把直播格式的m3u8文件当成点播来处理,例如自己编译一套ijkplayer源码来实现。

(2)每次seek 都是计算分片位置,播放指定分片就可以了。

优点:不用每次seek都请求m3u8文件,直接播放指定ts文件,体验非常流畅和点播seek一样

缺点:

(1)m3u8文件很大,http请求时 body增大 费流量,后台定时刷新这个文件、io性能也不高

(2)有技术门槛 需要自定义播放器解析播放的行为(c、c++)。

四、时移方案三,本地录制

这个方案简单粗暴,本地一边播放一边录制,时移就播放录制的内容,优点是本地播放真流畅,缺点是录制占用内存,耗费终端性能,没有录制的就不能时移,不推荐此方案。

 

 

总结:

追求用户体验、有播放器开发的技术能力,后台CDN配置高,可以采用方案二

从节省性能角度出发,可以采用方案一