本文對(duì)應(yīng)的音視頻預(yù)加載方案實(shí)現(xiàn)開源地址:https://github.com/zhuozp/VideoPreload
首先看下播放流程,了解播放過程中秒開的耗時(shí)在哪?如下圖,視頻從加載到播放的過程。
IO:為流獲取,可以從本地或者服務(wù)獲取
Parser:解析,如解析相關(guān)媒體格式,協(xié)議
渲染:展示內(nèi)容,顯示屏展示畫面,揚(yáng)聲器耳機(jī)播放聲音
流做到本地化就可以大大提高秒開的性能。因此,需要處理兩個(gè)事情,如何預(yù)加載以及播放器如何做到先從預(yù)加載播放,再從服務(wù)獲取流播放。
關(guān)于預(yù)加載緩存播放切換到服務(wù)獲取播放:
加入中間代理服務(wù),Proxy做到有本地緩存的數(shù)據(jù),從本地緩存數(shù)據(jù)返回,沒有的請(qǐng)求下,從服務(wù)獲取后,寫入到本地緩存中,再返回給播放器,這也是邊播邊緩存的情況。
在播放器中加入中間代理模塊,用的是AndroidVideoCache實(shí)現(xiàn)原理。中間代理開啟了8個(gè)并發(fā)線程的線程池做處理,因此,建議在播放的同時(shí),可以同時(shí)預(yù)加載載接下來的7個(gè)視頻流。
預(yù)加載處理
緩存播放到自然切換到服務(wù)播放有了,那么要解決的是,如何做到預(yù)加載的能力,這個(gè)不是依靠播放器提供的。如下圖的方案:
通過返回的各個(gè)視頻參數(shù)中的url或videoId生成md5校驗(yàn)值,根據(jù)md5判斷是否已存在任務(wù),沒有則生成任務(wù)并提交到線程池等待處理。線程池的線程處理主要是根據(jù)視頻Url生成本地代理Url,利用播放器的Proxy能力發(fā)起Http請(qǐng)求,從服務(wù)返回?cái)?shù)據(jù)。
預(yù)加載的過程需要處理Wifi切換到非wifi,線程停止下載,快速滑動(dòng)的情況,之前的任務(wù)停止等。