歡迎你們前往騰訊雲社區,獲取更多騰訊海量技術實踐乾貨哦~緩存
做者:蘆藝,QQ空間開發團隊一員性能優化
Qzone的日均視頻播放量已經突破了10億,其中Android端的播放量在總播放量中的佔比超過70%,相比年初,播放量的增加了超過10倍。視頻下載是整個視頻播放的基礎,若是下載側出問題,則會形成整個視頻播放的失敗,這就對咱們的視頻下載提出了很是高的要求。服務器
基於此,咱們將視頻下載總結爲"多快好省"四個方面,如下載成功率、首次緩衝時長和緩衝機率爲主要的技術指標對視頻下載進行優化。具體參數的優化結果見下表1,通過長時間的打磨,咱們的視頻下載模塊的下載成功率已經達到了99.9%,視頻的首次緩衝時長1.2秒,二次緩衝機率低於1%,取得了良好的效果。下面我將從"多快好省"這四個方面,對咱們主要的優化工做進行論述。網絡
表1: 下載相關技術指標優化先後對比less
技術指標 | 下載成功率 | 首次緩衝時長 | 緩衝機率 |
---|---|---|---|
優化前 | 97.1% | 2s | 15% |
優化後 | 99.9% | 1.2s | 0.9% |
在10億這個量級下,除了保證下載的成功率和下載速度這些主要參數以外,對於整個下載流程的監控、處理異常狀況顯得格外重要。爲了提高視頻的下載成功率、穩定性,監控整個下載流程,提高用戶體驗,咱們採用本地代理的方式進行視頻下載。工具
在Android手機上播放在線視頻,最簡單的方式就是實例化一個MediaPlayer, 將視頻的URL經過setDataSource()設置給播放器,以後調用prepareAsync()和start()遍能夠開始播放視頻。這種方式很是簡單,但其中最大的問題就是整個過程當中的數據流徹底由MediaPlayer控制,咱們沒法控制下載和播放的過程,也就致使咱們沒有辦法提升成功率,優化用戶體驗。所以,Android側的視頻下載通常採用本地代理的方案實現。本地代理的方案便是指在播放視頻的時候,將視頻的URL轉換爲本地URL(127.0.0.1開頭),在播放器經過本地URL請求視頻數據時,本地代理截獲此次請求,在通過本地的處理邏輯後,向服務器或者本地緩存請求數據。本地代理在得到視頻數據以後,將數據轉發給播放器,具體的流程以下圖1所示:性能
圖1:本地代理數據流測試
相比起直接由播放器請求數據,本地代理的優點是數據流由本地代理控制,咱們能夠在本地代理中加入緩存、預加載、防盜鏈等業務邏輯,這能夠極大的提高視頻下載的成功率,減小視頻的緩衝時間,從而提高用戶體驗。優化
傳統的本地代理方案確實解決了播放器直連帶來的問題,但一樣也會產生一些問題,視頻下載和播放的業務邏輯複雜,過多的邏輯和下載自己耦合,給開發的過程帶來極大的不便,而且這樣也不容易接入第三方的下載器和對下載過程進行監控。所以,在經歷了兩個版本的迭代以後,咱們將整個下載過程進行重構。此次重構使得下載各模塊的職責明確,便於開發、維護以及接入第三方的下載,也爲咱們後續的優化打下基礎,重構以後的方案會在以後單獨成文介紹。編碼
國外SmartBear的研究代表,57%的用戶在3秒沒有加載完網頁時就會放棄。在視頻播放上,加快視頻的加載速度,減小播放過程當中的卡頓,對提升用戶觀看視頻的體驗有極大的幫助。通過咱們長期的優化,如今Qzone視頻播放的接近秒開,緩衝機率降低到不到1%,這極大的提高了用戶體驗,也從側面提高了咱們的視頻播放量。
在這數據提高的背後,咱們主要作了幾個方面的工做:
盜鏈播放在國內很是廣泛,而盜鏈會使平臺資源流失,增長帶寬成本,不利於平臺的長期發展,國內大部分視頻服務提供商都在必定程度上作了防盜鏈。防盜鏈的主要過程是後臺下發的視頻URL,在正式播放以前,須要經過URL中的部分參數,加上一些本地參數,向後臺拉取真正播放的URL, 這些真正播放的URL都帶有時效性,這種方式能夠從必定程度上避免盜鏈行爲。但經過防盜連接口拉取真實的播放URL須要時間,這也在必定程度上延長了用戶感知的視頻加載時間。針對這種狀況,咱們對防盜鏈的模塊進行了改造,引入預拉取機制,將防盜鏈的拉取與播放解耦,對用戶的播放行爲進行預判,在用戶播放視頻的過程當中提早拉取並緩存以後視頻的URL, 從而減小了由於拉取防盜鏈URL形成的視頻緩衝時間。
圖2: 防盜鏈預拉取
從MediapPlayer的源碼能夠發現(AwesomePlayer.cpp), MediaPlayer須要下載5秒的數據纔會開始播放視頻,按照如今的外網平局下載速度計算,該過程的耗時在接近1秒,所以對於數據進行預加載是減小視頻首次緩衝很是重要的方法。但視頻數據的預加載不能跟當前播放的視頻搶下載帶寬,所以咱們選擇以當前播放視頻的播放進度和數據緩存量爲維度,當二者同時達到一個閥值時開始下載下一個視頻的數據。在實踐的過程當中,咱們還發現,由於一些編碼格式的緣由,MediaPlayer在播放視頻以前可能會請求一部分尾部數據,所以,視頻預加載還會加載一部分尾部數據,最大限度的保證預加載的效果。
MediaPlayer加載本地視頻的效率遠高於在線下載,所以,緩存的命中率會直接影響到視頻緩衝的速度。最初的緩存方案是針對單個視頻按照順序緩存,這樣實現簡單,但存在的問題就是沒法對於播放空洞(非順序播放場景,例如拖動、續播等)進行緩存,這下降了視頻的緩存率和緩存命中率,增長了帶寬成本和視頻的緩衝時長。以後咱們針對緩存模塊進行了改造,將順序緩存改成分片緩存,即將單個視頻的緩存按照必定大小進行分片,在遇到數據空洞或者緩存數據量達咱們設置的單片緩存上限時,開啓下一個分片緩存,確保能夠緩存全部的下載數據。這樣改造以後極大的提高了緩存命中率,下降了首次緩衝時間和二次緩衝的機率。
圖3: 緩存改造
梳理下載和播放過程當中總體的流程,經過工具排查流程中長耗時的點和優化過程當中的邏輯,減小沒必要要的耗時和操做,並將部分耗時邏輯移入子線程;優化時序,將例如圖片加載、緩存IO等重邏輯執行的時機後移,以及對視頻播放關聯度不高的邏輯使用懶加載。這樣能夠下降對於視頻播放,特別是視頻緩衝過程當中,CPU和IO的佔用,使得系統可以調度更多的資源在解封裝、解碼、渲染等與播放、下載直接相關的操做上,進而減小這部分的耗時。
下載的成功率是保證視頻觀看體驗的基礎,目前Qzone的視頻下載成功率已經提高至99.9%,跟主要命令字的成功率至關。國內的移動網絡環境錯綜複雜,不只要處理斷網、慢速、抖動等網絡自己的題,還要處理跨網、運營商劫持等國情問題。下載成功率的提高過程很是艱難,咱們在其中主要作了如下的工做:
經過IP直出減小了DNS劫持的可能性;對於下層代理的視頻下載下發多組IP,經過競速計算本地最佳IP,使用最佳IP進行直出下載;上層代理對於下層代理的整個下載過程進行監控,在監測到下載速度緩慢或者異常狀況時(IP鏈接失敗、數據讀取超時等)當即切換下載IP,減小用戶的視頻加載時間。經過IP直出、競速和切換,提升了下載的鏈接、數據讀取成功率,減小了因DNS劫持致使下載失敗的機率,同時提升了下載速度。
上文(2.1章節)中提到Qzone視頻播放的連接均是通過防盜鏈處理,帶有播放效期的連接,這就使得,在實際播放的場景中,極可能出現用戶但願播放某視頻時,跟隨後臺下發的視頻連接已通過期失效的狀況,若是不進行處理,則會極大下降下載的成功率。針對這種狀況,咱們根據視頻的不一樣來源,對於每種狀況進行異化處理,經過向後臺從新拉取連接或者本地計算Key,解決了因鏈接中的Key失效致使視頻沒法播放的問題。
Qzone很早就開始採用維納斯(WNS, Wireless Network Service)私有通道方案進行網絡數據傳輸,相比使用最多的Http方案,WNS經過長鏈接、IP直出、接入點優化、數據壓縮等方法,提升了網絡鏈接的成功率和穩定性。爲了提升主要命令字的拉取成功率,咱們對原有用Http拉取命令字的方式進行改造,使用WNS通道包裹原來的Http數據包,在後臺經過WNS通道收到原有的請求後再將請求分發至對應的後臺,具體的流程以下圖4所示。這樣經過低成本的改造(不須要修改原有協議,後臺直接透傳基本沒有開發工做量),藉由WNS提高了整個通道的傳輸質量,進而也提升了視頻的下載成功率。
圖4:下載命令字拉取接入私有通道
在移動網絡下,發生網絡抖動和網絡切換常常發生,但網絡不穩定,對下載來講是很是致命的。爲了應對網絡抖動和網絡切換,下層代理會監聽當前的網絡變化,監控當前的下載速度。下層代理在下載數據時,爲了減小對於別的業務影響,不會佔用所有的帶寬,但當發生頻繁的網絡切換時,下載代理會主動突破速度的限制,儘量快的在網絡狀況良好時下載數據,給以後的播放留下足夠的數據Buffer,保證總體播放的流暢性。
互聯網的視頻服務提供商在國內盈利極其困難,除了近幾年視頻市場競爭愈來愈激烈,版權費居高不下以外,國內高昂的帶寬成本也是重要緣由。所以,如何在保證視頻質量的前提下,儘量減小下載流量,減小下載而產生的帶寬成本,對於咱們來講也是很是重要的工做。在這部分,咱們主要的工做以下:
爲了保證用戶觀看的流暢性,減小視頻緩衝,視頻數據下載的可播放量與當前觀看的時間點以前會保持必定的Buffer,在整個播放過程當中,經過動態調節下載速度,這個Buffer的大小基本保持不變,而且Buffer的大小能夠動態調節。在流量高峯的時間段,咱們會經過後臺進行流量控制,減小Buffer,也就減小了高峯時段總體的下載量。帶寬的計費標準通常按照高峯流量計費,減小了高峯時段的流量,也就下降了帶寬成本。具體流控以下圖,高峯時段視頻緩衝M秒,非高峯時段緩衝N秒,N>M,兩個參數都可由後臺控制。
圖5:流量控制
H265是新一代視頻編碼標準,相比原有使用H264編碼的視頻,具備更高的壓縮比,在畫質近似的前提下,H265編碼的視頻文件體積只有H264的一半甚至更少,所以,播放H265編碼的視頻能極大減小帶寬消耗。但H265現階段主要存在的問題是終端編碼耗時過長,後臺編碼過於消耗資源,以及在Android手機上,軟解碼(Android支持H265硬解碼的機型較少,而且硬解碼的兼容性問題相比軟解更多)帶來的耗電、發熱以及兼容性問題。目前,Qzone經過自解碼播放器,在通過大量的兼容性測試以後,已經在超過100款主流Android手機上實現了H265視頻的軟解播放。空間視頻H265和H264編碼的下載帶寬對比以及以後的預期狀況以下圖6所示,能夠明顯看出,經過H265編碼極大的下降了咱們的視頻下載帶寬成本。
圖6:空間視頻H265和H264編碼下載帶寬比較
另外在2.3中論述對於視頻緩存的分片改造,同時提高了下載數據緩存的使用率和命中率,也了減小了咱們的視頻下載帶寬。
通過長時間的優化,Qzone視頻業務,包括下載成功率、播放成功率、緩衝機率、首次緩衝時長等在內的主要技術指標,均獲得了大幅度的提高,達到了咱們的預期,也爲Qzone視頻點播和直播業務的持續發力鋪平了道路。但技術優化是一個長期的過程,目前Qzone的視頻播放已經開始啓用自解碼播放器,逐步替換原生的MediaPlayer,以後咱們還會經過播放器多實例,編解碼,參數調節等方式進一步提高視頻下載成功率,壓縮視頻緩衝時間,減小緩衝機率。也歡迎各位多使用Qzone體驗咱們在各個場景中的視頻播放,若是對體驗或者技術優化的建議和意見,歡迎交流。
Qzone Android視頻點播技術優化小分隊:joltwang, michalliu, erainzhong, zakiwang,magilu.
同時感謝騰訊視頻hualiangyan的長期支持。
周杰倫讀心術背後的技術實現
十億級視頻播放技術優化揭密
HLS 視頻點播初探
此文已由做者受權騰訊雲技術社區發佈,轉載請註明原文出處
原文連接:https://cloud.tencent.com/com...