本文主要分享播放器的性能優(yōu)化,本文只是方法論的總結(jié),不會(huì)涉及具體的方式,如果想深入學(xué)習(xí)播放器優(yōu)化請(qǐng)查看:
https://mp.weixin.qq.com/s/oL22a68Tmr2ViE3DK6Qk1g
https://mp.weixin.qq.com/s/K8DLM4X-sMghAaX5y1zFuA
1.播放指標(biāo)
- 播放成功率
- 播放成功次數(shù) / 播放總次數(shù)
- 視頻播放首幀(秒開率)
- 調(diào)用start ~ 視頻首幀送入Render
- 首幀在1s的次數(shù) / 總次數(shù)
- 視頻播放卡頓率
- 卡頓總時(shí)長 / 觀看時(shí)長
- seek拖動(dòng)卡頓
- seek拖動(dòng)卡頓次數(shù) / seek總次數(shù)
視頻播放成功率現(xiàn)在都比較高了,一般都是自建的源或者使用頭部云平臺(tái)的服務(wù),不會(huì)存在格式不支持的問題了。
現(xiàn)在比較重要的兩個(gè)指標(biāo)就是視頻播放首幀和視頻播放卡頓率
2.視頻首幀優(yōu)化
- TCP請(qǐng)求連接復(fù)用
- 請(qǐng)求的域名可以枚舉出來,可以預(yù)連接,后續(xù)復(fù)用
- 預(yù)建解碼器
- 后臺(tái)下發(fā)視頻信息,預(yù)先創(chuàng)建解碼器
- 解碼器復(fù)用
- 預(yù)渲染
- 首先將首幀渲染出來
- 預(yù)加載
- 頭部設(shè)置probesize和analyzeduration設(shè)置請(qǐng)求的大小,保證預(yù)先請(qǐng)求足夠的數(shù)據(jù)以供后續(xù)渲染
- 指定格式
- 指定特定的解封裝格式
- 指定特定的解碼格式
- 邊下邊播
- 本地代理實(shí)現(xiàn)邊下邊播,可以復(fù)用之前緩存
- video-id復(fù)用
- 同一個(gè)視頻url會(huì)經(jīng)常變,但是video-id不變,用video-id作為視頻緩存的key
- 低碼率首幀加載
- 開始播放使用低碼率的片源,等后續(xù)播放穩(wěn)定切換到高碼率的片源
3.視頻卡頓優(yōu)化
- 解決渲染卡頓
- 播放幀渲染不能有耗時(shí)操作,例如視頻播放中美顏、濾鏡等操作不能耗時(shí)
- 加載Buffer優(yōu)化
- 網(wǎng)絡(luò)好的情況下緩沖Buffer調(diào)大點(diǎn)
- 網(wǎng)絡(luò)差的情況下緩沖Buffer調(diào)小點(diǎn)
- 多碼率適應(yīng)
- HLS多碼率適應(yīng),弱網(wǎng)情況下計(jì)算load buffer自動(dòng)切換到低碼率
- 丟幀控制
- 極端情況下適當(dāng)丟幀,丟幀要優(yōu)先丟非參考幀,可能得話丟一整個(gè)GOP的數(shù)據(jù),防止出現(xiàn)花屏
- 音視頻同步
- 推流端推的視頻timestamp和音頻timestamp有問題,拉流端音視頻同步存在問題,導(dǎo)致播放卡頓,需要推流端校準(zhǔn)
4.Seek優(yōu)化
拖動(dòng)進(jìn)度條是一個(gè)比較重要的優(yōu)化項(xiàng),ffmpeg中的av_seek_frame有下面幾種選項(xiàng):
- AVSEEK_FLAG_BACKWARD:第一個(gè) Flag 是 seek 到請(qǐng)求的時(shí)間戳之前最近的關(guān)鍵幀。通常情況下,seek 以 ms 為單位,若指定的 ms 時(shí)間戳剛好不是關(guān)鍵幀(大幾率),會(huì)自動(dòng)往回 seek 到最近的關(guān)鍵幀。雖然這種 flag 定位并不是非常精確,但能夠較好地處理掉馬賽克的問題,因?yàn)?BACKWARD 的方式會(huì)向回查找關(guān)鍵幀處,定位到關(guān)鍵幀處。
- AVSEEK_FLAG_BYTE :第二個(gè) Flag 是 seek 到文件中對(duì)應(yīng)的位置(字節(jié)表示),和 AVSEEK_FLAG_FRAME 完全一致,但查找算法不同。
- AVSEEK_FLAG_ANY:第三個(gè) Flag 是可以 seek 到任意幀,不一定是關(guān)鍵幀,因此使用時(shí)可能出現(xiàn)花屏(馬賽克),但進(jìn)度和手滑完全一致。
- AVSEEK_FLAG_FRAME:第四個(gè) Flag 是 seek 的時(shí)間戳對(duì)應(yīng) frame 序號(hào),可以理解為向后找到最近的關(guān)鍵幀,與 BACKWARD 的方向是相反的。
- 當(dāng)前播放時(shí)間點(diǎn)是cur_time,拖動(dòng)到的時(shí)間點(diǎn)是seek_time,如果seek_time和cur_time在同一個(gè)GOP內(nèi)部,那就不需要清空video frame queue中數(shù)據(jù),優(yōu)化seek性能。