導語:QCon是由InfoQ主辦的全球頂級技術盛會,每年在倫敦、北京、東京、紐約、聖保羅、上海、舊金山召開。自 2007年 3月份首次舉辦以來,已經有超萬名高階技術人員參加過QCon大會。QCon內容源於實踐並面向社群,演講嘉賓依據熱點話題,面向 5年以上工作經驗的技術團隊負責人、架構師、工程總監、高階開發人員分享技術創新和最佳實踐。
4月18日效能優化面面觀專題會議上,騰訊研發總監王輝以“十億級視訊播放技術優化揭祕”為主題,用QQ空間的日均播放量一年內從千萬級突破到十億級所面臨的嚴峻考驗為切入點,為大家分享視訊團隊在視訊元件的整體架構、優化效果衡量、頻寬優化、秒開優化、緩衝優化、成功率優化等六個方面的技術實踐。
王輝:大家早上好!我叫王輝,來自騰訊,從2009年開始從事QQ空間技術研發,近期主要關注手機短視訊、視訊直播、AI智慧硬體。很高興能在QCon上與大家一起分享和交流。我今天的話題是“十億級視訊播放技術優化揭密”。主要介紹我們團隊在去年一年短視訊風口上,我們的視訊播放量從5000萬到十億級過程中的一些技術實踐,希望我的介紹能給大家做一些借鑑和參考。
眾所周知,短視訊去年是一個風口,起因是來自Facebook 2015年Q3的財報,財報表明在Facebook平臺上每天有80億次短視訊播放,給Facebook帶來了強勁的廣告收入,正是這個資料給國核心心大公司和創業公司帶來的一些新的突破口。其實短視訊已經不是一個新的概念,從2006年開始國內就有很多公司在做短視訊。隨著Facebook吹起短視訊風,去年在短視訊行業有近百款應用出現,中國網民裡面每5個裡面就有1個是短視訊的使用者,短視訊成為網際網路的流量入口。QQ空間也在這個風口中,從2015年11月份的每天5000萬視訊播放量,經過一年的耕耘細作,徒增到2016年12月份的10億量級,現在還在不斷增長。
我的演講主要是按照我們產品迭代的幾個關鍵步驟展開:
首先是快速上線,2015年我也是跟隨著大家的體驗快速上線了新短視訊的體驗;
其次面臨的是成本問題,在做的過程中做了一些成本的優化工作;
然後是體驗優化。在解決成本問題之後,短視訊的觀看體驗要做到極致。比如說視訊的秒開、不產生緩衝、不卡、成功率的提升。
快速上線
在開始之前,我先介紹一下我們的團隊職責,我們團隊負責手機QQ和手機QQ空間兩個APP,每個APP有iOS和Android兩個團隊,一共四個團隊,四個團隊負責兩個APP。在這個專案中,我們四個團隊要針對兩個平臺實現四套邏輯,這裡的效率是存在一定的問題。
關於短視訊體驗,在這之前,我們也只是做到能播放而已,沒有做很精細的工作,並且這裡的產品觀感體驗也不是很一致,也不是很好。
技術上,之前也只是做很基礎的架構,直接由播放器連線伺服器下載資料,達到能播放就可以。之前我們沒有積極去做這個事情,導致播放成功率低、失敗原因未知、不支援邊下邊播、緩衝時間比較長等問題,流量浪費也比較嚴重。在產品上要解決的,是在整個APP裡面把所有產品的體驗做到一致,比如說每個功能的觀看體驗,視訊浮層的體驗,統一觀看體驗也為我們專案清除了很多障礙。
而這裡的技術上的要點是非常關鍵的,第一個是邊下邊播,這是基礎的要求,是為了加快視訊播放速度。第二個是流量的控制,這麼大的平臺,之前只是做5000萬的播放量,如果沒有流量控制的雲策略,可能到後面流量是無法把控的。第三,剛才講到團隊的現狀,團隊要負責兩個APP,這裡要做程式碼複用,不可能再像之前一樣四個團隊維護四套程式碼,第四,我們支援第三方的視訊源。第五,需要完善監控上報,對業務知根知底。
可以看到,完成核心技術要點最核心的一點是如何控制視訊的下載,傳統的方式是播放器直接塞播放地址給播放器,它就可以直接播放,這其實是一個黑盒。我們在中間加了一個本地代理,播放器與伺服器的資料請求,我們完全可以把控。在這個過程中,比如說播放器要資料時,可以給它更多的資料,這樣能解決它緩衝的問題。有了這層代理之後,架構也更清晰一點。
基於這樣的架構,在MODEL一層做一些業務的邏輯,在VideoController這一層做控制視訊的播放和下載。有了下載代理之後,就可以通過代理管理下載,在APP裡面有很多的視訊請求,VideoProxy可以管理這些請求,做流量控制,做預載入,還可以做優先順序排程和做監控上報,下載邏輯層則主要關注怎麼優化伺服器,對接快取管理層,同時我們抽象出了一個資料層,我的資料來源可以是HTTPDataSource,也可以讀本地,也可以是來來自騰訊視訊的資料來源,也可以是第三方APP的資料來源,協議層主要是HTTP、HTTPS、HTTP2的解決。
在VideoController的邏輯裡,其實都可以放到C層來實現,這樣安卓和iOS完全可以通用,這一層的邏輯可以在QQ和QQ空間兩個APP裡面使用,相當於是我們一套邏輯可以完全複用,不用再開發四套邏輯,我們團隊的職能也做了相應調整,之前可能是按團隊劃分,四個團隊負責四個終端,現在可能是按FT的方式劃分做視訊的團隊,iOS做視訊的團隊可能負責QQ和QQ空間裡的業務,安卓也是如此。直播的FT也可以這樣劃分,iOS的負責iOS的兩個APP,安卓的負責安卓的兩個APP,這樣程式碼複用更清晰一點,我的團隊更專注一點。視訊的團隊專注視訊的研發。
監控上報,肯定是不可缺少的,這是一個成熟的專案必備的要素。
問題定位,老闆跟使用者反饋說我這個視訊播不了,要有一套成熟的問題定位的方式;
耗時統計,使用者播放這個視訊花多長時間播出來,這也是要了解到的;
成功率統計,外網使用者播放視訊的成功率是多少?還要通過實時報警,才能及時知道外網發生一些故障。
傳統的撈Log方式大家都有,但是這種方式效率太低,需要等使用者上線之後才能撈到Log,Log撈到之後還得花時間去分析。我們做法的是在關鍵問題上做一些插裝,把每一類錯誤和每一個具體的子錯誤都能定義出來,這樣一看錯誤碼就知道播放錯誤是由什麼原因導致的。還可以把每次播放視訊的鏈路所有關鍵流水上報到統計系統裡來,每一次播放都是一組流水,每一條流水裡面就包含了例如首次緩衝發生的Seek,或下載的連結是多少,下載的時間是多少,有了這些流水之後,使用者反饋播放失敗,我首先可以用流水看發生了什麼錯誤?錯誤在哪一步?每一步資訊是什麼?幾秒鐘就可以定位到問題。
有了這個資料上報之後,還可以做一些報表。比如說可以做錯誤碼的報表,有了報表之後就可以跟進哪個錯誤是在TOP的,負責人是誰,原因是什麼,都可以看到。
我們也有自己實時的曲線,可以看到各項資料的情況。在告警方面,基於成功率和失敗率的統計,進行實時告警。一出現錯誤碼,微信立即可以收到提醒,提醒說是什麼原因導致這次告警,全自動。
成本優化
上線一個月之後,一個壞訊息一個好訊息。好訊息是播放量漲了4倍,壞訊息是頻寬漲了6倍。頻寬優化是每個做視訊的人必須要面臨的問題,我們也分析這個過程中的原因,發現因為改為邊下邊播之後使用者觀看視訊的意願比較強,使用者有挑選心理,不是每個視訊都去看,看了一下之後不喜歡就划走了,之前下載的那部分其實是浪費的。如果之前不做限速的話,一點開視訊就瘋狂的下資料,頻寬有多大就下多少的資料,這樣浪費很嚴重。
我們採取的第一個策略是進行流量控制。在高峰期播放到第10秒時,預下載N秒資料,下載到N秒就停下來。然後,可以做多級限速。一開始不限速,下載到合適時機做1倍位元速率限速。高峰期時預載入的資料會少一些,防止高峰期時頻寬佔用明顯,這是初級的策略。最終我們也有位元速率切換的策略。這對使用者的觀看體驗影響比較大,這也是之前必備的一個策略。
上線這個策略之後,對頻寬的優化還是比較明顯的。在高峰期時從18:00到凌晨1點頻寬下降25.4%,這個是我們不斷灰度最終確定的值。這個值會影響播放緩衝,因為資料少的話必定會卡頓,在卡頓之間和流量之間取了一個最優值,最終是25.4%.
但這樣肯定是不夠的,因為流量漲的還是很明顯的,我們想到H.265,壓縮率相對於H.264提升了30%-50%,但它的複雜度也是呈指數級上升。複雜度導致它的編解碼耗時更長,佔用資源也更長。如果把H.265用在客戶端上的話,可能要評估一些點,比如說在編碼上面,現在手機上沒有做H.265硬體支援的,相對於H.264的耗時3-7倍,之前耗時可能是10分鐘,而現在可能需要到70分鐘左右。解碼的硬體支援H.265的也很少,耗時差不多是一樣的。解碼是可行的,你可以採用軟解的方式,這個帶來的問題是CPU佔用非常高,可能之前H.264佔20%的CPU,H.265佔70%、80%左右,帶來的問題是發熱和耗電。
結論,解碼是可行的,但是編碼不用考慮,在移動客戶端不可行的情況下,那編碼就要放在後臺來做了。
為了解決如何在我們手機上能夠解碼的問題,對手機的解碼能力做一次評估。我在合適的時機做一次大規模的浮點數運算,將資料上傳到後臺伺服器進行雲適配。如果當前的指數滿足H.265條件的話,可以給你下載H.265視訊給你播放。從而保證軟體解碼柔性可用,針對視訊源規格按機型適配降級,保證使用者視訊播放體驗。
經過我們的統計,外網上有94%的手機還是支援H.265解碼的。支援1080P手機的解碼佔46%.
編碼只能在後臺做,如果在視訊後臺進行全面編碼的話,是不現實的。因為編碼複雜度呈指數級上升,拿後臺伺服器進行編碼也是不可行的。我們的做法是隻用熱點視訊進行後臺轉碼,不是所有視訊都去編碼,對觀看量在TOP N的視訊進行編碼,只需要編碼少量的視訊就可以帶來流量優化效果,因為TOP N就佔了全網80-90%的流量。
因為熱點視訊的熱點轉化很快,可能前幾分鐘是熱點,後幾分鐘就不是熱點,因為社交網路的傳播非常快。我們給後臺的要求是轉碼速度一定要快,在之前沒有優化時,轉一個10分鐘的視訊要半個小時左右。後來我們做了分散式處理之後,轉10分鐘的視訊只用兩三分鐘。一些短視訊最長5分鐘左右,只要監測到這個視訊很熱的話,1分鐘之內就能轉出來,就是H.265了。
同樣,在H.265編碼器上做了一些優化,比如說編碼速度和位元速率的都會有提升。
上線H.265優化之後,我們的頻寬進一步下降,節省了31%左右。
秒開優化
頻寬問題解決之後,面臨的下一個問題是體驗優化。使用者最想要的是視訊能立馬播出來。我們定了一個秒開技術指標,只要這個視訊從到我的視野範圍,到視訊播出來之間的耗時在一秒以內。這也是對標Facebook的體驗,Facebook一開啟動態,視訊是能立即播出來的,不需要等待就能播,這個體驗其實很順暢。核心的流程主要是三個步驟:1、客戶端的耗時;2、下載資料;3、等待播放。
這裡主要有兩個大的耗時點,第一下載視訊資料耗時;第二個是客戶端的耗時,下載視訊資料耗時的話,主要是下載資料量和下載的速度。
這裡有一個很直接的問題,播放器需要下載多少資料才能播放?我們可以看一下MP4,MP4其實是一個比較靈活的容器格式,每個東西都是用Box表達的,每個Box又可以嵌入到另外一個Box。MP4主要由MOOV和Mdata組成,MOOV是囊括了所有的視訊關鍵資訊,肯定是先把MOOV下載完之後才能找視訊資料才能播起來。不巧的是,在我們外網會發現有5%左右使用者上傳的視訊,它的MOOV是在尾部的。後來也發現,有很多安卓手機比如說山寨機,一些攝像頭處理的廠商可能比較偷懶,因為他們只有在你採集完資訊之後才能知道他所有的資訊,他可能把所有的資訊放在尾部。對於MP4來說,一開始把頭部下載了,下載頭部時可能找不到這個MOOV,就猜測這個MOOV在尾部,我可能就有一次請求去探測這個頭部到底在哪?這個探測的話基本做法是去尾部探測。如果MOOV在其他地方的話,這次播放肯定是失敗的。現在主流的系統都是去尾部進行一次探測。
比如安卓某些手機是無法自定義Range,那就需要下載完整個檔案才能播放。我們的處理方式,使用者在後臺做一次轉碼修復,客戶端採集後做一次轉碼修復。
再看一下Mdata,這是視訊的原資料。目前大部分是H.264編碼,H.264通過真預測的方式來進行視訊編碼,這裡有一個GOP概念,也是在直播裡面經常談的。一般的視訊需要下載歌完整的GOP資料才可以播,可以看到在這個裡面需要下載多少資料才能播呢?每個播放器的行為也不一樣。大家可以看到iOS要下載一個完整的GOP才可以播。像FFmpegBasedPlayer的話我可能只需要關鍵幀就可以播出來。安卓是比較尷尬的一個系統,在6.0級以下,可能需要5秒視訊資料才可以播起來。如果說是需要下載5秒資料才可以播起來的話,那肯定是非常慢的。我們這裡的一個策略會採用FFmpegBasedPlayer自己來做解碼,這裡要關注功能性和耗電的問題。
解決了Mdata之後,你會發現如果我的資料在頭部,拿關鍵資訊進行播放的話,其實我播放的資料量非常小的。
對於下載優化的話,會有一個防盜鏈的請求,通過HTTP拿到真實的才可以下載資料。在手機上執行HTTP請求是非常耗時的,這裡我們走私有長連線通道做這個事情。
關於優化下載鏈路,這裡也是談的比較多的,一般也是直接輸出IP地址,利用IP地址做跑馬的策略,兼顧效能的效率,這個是用的比較多的方式。
進一步思考,按照普遍600K位元速率的話,我們統計到現在APP上面下載的平均速度是400K左右,這樣計算的話,可能在安卓上面播放一個視訊的話,需要將近0.9秒左右才可以下載到你需要的資料。如果位元速率再進一步提升的話,可能會更大,這其實我們也做了一些場景分析,會發現我們是社交網站,它有好友動態,視訊在好友動態裡播放,或者是在視訊浮層裡播放,我們的選擇是預載入的策略,這也是常見的策略。我們會在當前看的這條動態時會預載入後面視訊的關鍵資訊,比如說會載入頭部資訊和需要播放的資料,來進行預載入。比如說在播放當前視訊時,我的視訊在載入一定資料之後會載入下一秒預載入資料,這些都可以做到的。
預載入有一個問題,我們之前踩了一個坑,可能預載入視訊時還是要優先圖片的。視訊當然重要,但是社交網路上的圖片也更重要,可能在預載入視訊時會考慮到圖片的一些任務,還有視訊封面之類。
優化效果也是比較明顯,經過剛才幾個策略,一個是我們對頭和播放器的處理,我們對防盜鏈的處理,還有對下載鏈路的處理和預載入,這樣我們的耗時大幅度減少了,之前是1.8秒降到0.6秒左右。客戶端的效能也是讓人容易忽視的問題,發現有些使用者雖然有視訊的快取,但是播起來還是很慢,這其實是客戶端效能的影響。因為視訊涉及到的BU和流程比較多,在這個過程中還要更關注到客戶端的影響,要分析下客戶端是哪些在搶佔你的視訊播放資源,我們之前犯過一些錯誤,md5會卡住一些流程,或者是HttpParser會阻止你的任務,會導致視訊播放更慢。
在優化視訊播放過程中,我們在4月份也做直播。直播這裡面插入個事情,我們要播放直播的視訊流,是HLS的視訊,在好友動態裡面可以觀看直播的內容。HLS在安卓上面體驗非常差,因為安卓3.0之後對HLS基本沒有做的優化工作,這裡每次安卓上播放HLS需要等待6-9秒。分析發現它的處理也不是很得當,因為安卓系統請求鏈路較長,序列下載,需要下載3-4片TS才能啟動播放,下載3個分片的話,耗時就會很久。之前提到我們這裡有代理,有了代理之後做事情方便很多了,通過裡獲取M3U8,解析M3U8裡面有哪些檔案,可以做並行下載,只讓他下載一次M3U8,這樣下載速度大幅度提升。回到剛才架構上,有了下載代理層的話,你可以做HLS的加速和管理,可以加入HLS的視訊源。
HLS緩衝耗時也是很明顯的,之前需要6秒左右,現在1.6秒左右就可以播起來。整體從之前的2秒左右現在優化到700m秒,80%使用者都可以在1秒內播視訊。
還有一個是使用者比較關注的問題,觀看視訊時卡,觀看一會卡了一下,loading資料,loading完以後又卡,這個體驗非常差,我們希望所有的視訊都不卡。其實這有兩個播放場景,一個是正常場景,邊下邊看,資料在下載。對於正常場景下載時會做一些頻寬調整,在低速時會做切換IP的處理,比如說當前連通IP的耗時比較久的話,會做一些處理,也會對網路進行速度限制。
針對Seek場景的話,如果使用者拖動的話,檔案快取系統是連續儲存系統的話,必然會造成拖到這裡時,後面的快取資料是沒有辦法下載到系統裡面來的。
我們就對儲存做了一次重構,支援檔案空洞。會按照一兆的方式對檔案進行碎片劃分,好處是我可以分段儲存,我可以允許邏輯空洞的,拖動的話也可以在後面儲存,也不需要資料庫,我可以知道這是從哪個位置到哪個位置的儲存。這樣淘汰快取也高效一點,並可以制定更靈活的快取策略。這裡可以淘汰更低密度的檔案,還可以做的事情是對檔案加密。這裡產生卡頓的使用者裡面,90%是因為進行拖動,拖動之後又沒有快取資料,所以這裡有可能導致發生緩衝。統計效果也是比較明顯的,上了分片快取之後,之前的快取概率是4.6%左右,最後下降到0.48%,基本上看不到發生緩衝的場景。
成功率優化,也是我們比較關鍵的指標。成功率優化沒有捷徑,可能是Case by Case各個擊破。之前我們進行編碼,有幾百個錯誤碼,錯誤碼原因進行上報,每次進行迴圈,一個個錯誤碼進行解決。下載常見的錯誤碼,DNS劫持是比較多的,一些網路運營商會劫持你的請求。
這個在國內是比較常見的劫持,有的小運營商按月會劫持你的視訊內容,可能直接汙染你的DNS讓你查詢不到CDN,這是比較多的,還有一些網路不穩定的影響導致。更隱藏的會直接汙染你的視訊內容,讓你視訊內容是錯誤的。播放比較多的可能是一些編碼的原因,剛才提到一些手機採集出來的視訊在低端手機上播不出來,我們會對這些視訊進行修復。
邏輯上的問題,因為播放器有狀態的,可能開發人員比較多,每個人過來加一個邏輯的話,會導致播放狀態出現問題。
我們做的播放器錯誤解決方法:
HOOK播放器介面與回撥,實現播放器狀態機,監控插放器API的呼叫是否合法,不合法直接告警或Crash。幫助開發快速定位問題,同時減輕測試同事的負擔,封裝成UI元件,使其它開發不必理解播放器。
最終優化的成果是這樣的,下載成功率優化前是97.1%,優化後是99.9%。播放成功率優化前是97.0%,優化後是99.9%。首次緩衝耗時優化前是1.95s,優化後是0.7s。二次緩衝概率優化前是4.63%,優化後是0.48%。資料還是很可觀的。
我的演講基本是這些,歡迎大家關注我們團隊的公眾賬號,也會分享一些技術文章。
Q&A
問題1:剛才您提到已經開始嘗試用265了,能透露一下265你們播放的在整體中佔多大的比例?
王輝:現在熱視訊裡面80%都是H.265。10億裡面會有70%、80%左右。
問題2:推進的還是挺靠前的。剛才你提到要判斷手機的H.265能力,用大規模的浮點運算,首先我先了解一下你們用的什麼浮點運算的Mark?其次,為什麼要用浮點運算?其實視訊編解碼裡面幾乎全部都是整數運算。
王輝:浮點運算能代表你這個手機效能,其實我們是評估效能的,不是評估H.265轉碼,如果效能達到的話,解碼也是可以達到的。
問題3:如果想針對解碼做評估的話,我建議整數運算。你可以確認一下,首先視訊編解碼的標準規定是沒有浮點運算,不同的編解碼時限可能會插入少量的浮點運算,大部分是整數運算。
王輝:我們初步做的時候是判斷手機有沒有運算能力來做的浮點運算判斷。
主持人:感謝各位嘉賓的提問,感謝王輝老師給大家帶來的講解。
相關閱讀
周杰倫讀心術背後的技術實現
點播檔案防盜鏈二三事
HLS 視訊點播初探
此文已由作者授權騰訊雲技術社群釋出,轉載請註明原文出處
原文連結:https://cloud.tencent.com/community/article/446586?fromSource=gwzcw.632156.632156.632156
海量技術實踐經驗,盡在騰訊雲社群