本文字數: 2259 字
預計閱讀時間: 10 分鐘
視訊起播時間,即首幀時間,是視訊類套用的一個重要核心指標,也是影響使用者觀看體驗的核心因素之一。如果視訊要載入很久才能開始播放,使用者放棄播放甚至離開 App 的機率都會增加。
視訊秒播是指使用者在起播時平滑播放,沒有首屏的頓感,使用者幾乎感知不到有首幀時間的存在。
我們把從開始播放到視訊首幀畫面展現出來這個鏈路的耗時稱為首幀耗時,想要最佳化首幀耗時,達到秒播效果,我們需要知道這個鏈路上,都進行了哪些步驟,然後找到其耗時點,進行針對性最佳化。不同的業務場景下,播放行為和播控策略不盡相同,最常見的就是冷啟動場景、短視訊場景、頁面切換場景以及長視訊場景。本文主要討論具體業務場景下的最佳化實踐,我們可以根據場景的特性,采取不同的最佳化策略。
01
通用首幀最佳化方法
1.1提前獲取播放地址
視訊播放的第一步就是獲取視訊資源的播放連結,通常而言,視訊資源會有唯一標識 video id ,在點播的伺服端會有一個根據 video id 獲取播放連結的服務,如果將播放地址隨 feed 流一起下發,或者播放前提前請求,則省去了客戶端的一次網路請求耗時。
1.2預載入
預載入是一種常見的首幀最佳化措施,我們可以提前下載部份視訊數據以達到快速起播的目的。但是什麽時候去預載入、預載入多少、並列預載入數量等都是實際需要考慮的問題。
首先是預載入時機的問題,預載入時機如果太晚,幾乎沒有效果;如果太早,可能會跟當前正在播放的視訊搶奪寶貴的頻寬資源,甚至造成播放卡頓。我們必須要遵守一個原則:視訊預載入絕對不能影響到當前視訊的播放。 一個簡單的方案就是,當前視訊緩沖到一定比例,再進行下個視訊的預載入。當然還有更加細致的方案,根據當前播放視訊的可用緩存、當前網路的下載速度、當前視訊的碼率以及即將預載入視訊的碼率、並列預載入數量,透過這些數據我們能夠構建一個模型去預測接下來視訊播放的卡頓狀況,如果大機率是不會發生卡頓,則可以開啟預載入,反之則不啟用或者暫停預載入。
另外一個問題,預載入多少,直觀認識,至少得保證首幀能載入出來。一個粗略的估算方法是 moov 大小加上視訊的平均位元速率 * 預載入時長,這樣就可以透過伺服端下發 moov 頭大小及視訊的平均位元速率,然後在 App 端上透過實驗去調整預載入時長參數,進而調整預載入大小。
1.3預渲染
透過預載入只能夠將網路請求的耗時消除掉,但播放器還是需要經歷解復用、解碼、渲染的步驟,在中低端機器有 200 毫秒以上的耗時。如果能夠將視訊的首幀提前渲染好而不播放,將會縮減掉這部份的耗時。而預渲染就是提前將視訊的首幀渲染出來的技術。
具體來說,預渲染會提前解碼出視訊首幀,並且將首幀渲染出來,但是這個過程中音訊不會播放出來。在滑動播放場景,當滑動視訊卡片時,就已經開始啟動預渲染,在卡片滑動過程中,視訊的首幀很可能就已經透過預渲染載入出來,這樣當卡片滑到中央時,則直接啟動播放,這時候使用者基本上感受不到視訊的載入。
02
分場景最佳化實踐
2.1冷啟動場景
冷啟動場景下能做的最佳化空間較小,主要兩個思路:
一、在 App 啟動最早的時候( Application 建立時),開始異步初始化播放器元件,讓播放器盡早 Ready ;
二、在不影響體驗的情況下,選擇碼率低的檔位起播。
2.2短視訊滑動場景
短視訊沈浸式滑動播放場景,可以采取雙播放器例項載入復用的策略,播放當前視訊的同時,第二個播放器載入即將播放的視訊,渲染首幀後暫停,列表其他視訊進行預載入(預載入是純下載的過程,無渲染邏輯)。
另外,還有滑動過程中調播的最佳化,在滑動松手 scrollViewWillEndDragging 時就可以計算出待播放的視訊,無需等到滑動停止 scrollViewDidEndDragging ,手指擡起就開啟播放,可節省 300 毫秒左右的耗時。
在增加了下一個視訊的 「預播」 機制後,使用者滑到下個視訊時,可以立即從首幀的暫停狀態恢復為播放,不再需要預先顯示封面圖,也提高了播放體感上的速度。除視訊以外的業務數據的渲染,可以放在使用者滑動翻頁的過程中進行。
基本流程如下圖:
2.3頁面跳轉場景
進入新頁面時,總需要先請求播放數據及業務數據,然後再載入播放視訊,這個過程會讓使用者感知到等待時長。 播放頁面之間的跳轉,有兩種情況:
一、播放中視訊的跳轉;
二、未起播視訊的跳轉。
針對情況一的最佳化策略為:無縫切換,不打斷當前視訊的播放,實作播放器在兩個頁面間的轉移,真正做到「零耗時」體驗。
針對情況二的最佳化策略為:在跳到新頁面時需要前頁面傳入 videoUrl ,提前進行播放,同時進行業務數據的請求和渲染。這樣保證了視訊與業務數據的載入可以異步執行,由於使用者主要目光是集中在視訊上的,所以從使用者的視角直觀的來看,頁面載入速度變快了。
2.4長視訊場景
長視訊場景下可做的最佳化,一個是關鍵幀起播。長視訊一般是從播放進度處起播,通常的實作方式是 seek 到歷史進度前面最近的一個關鍵幀,然後把視訊幀塞給解碼器,在解碼器中做丟幀處理,直到 pts 到了指定的歷史進度。假設這個視訊的碼率是 2.5Mbps ,視訊的 GOP 大小為 5s ,那麽精準 seek 的起播,最壞情況需要額外下載 2.5 * 5=12.5Mb 的數據。如果我們只在關鍵幀位置起播(非精準 seek ),則可以避免這些額外數據的下載,從而縮短首幀的耗時。
另一個是連播預載入,連播場景下是可以定位使用者接下來要播放的視訊的,可以采取提前獲取播放地址,並進行預載入的策略,提高連播視訊的起播速度。
03
總結與展望
本文介紹了通用的幾種首幀最佳化方法,以及各實際業務場景中的不同最佳化策略,我們在計畫開發中也在持續最佳化實踐。客戶端受網路環境、高中低各種機型、使用者使用習慣等影響,無論是預載入、預渲染策略,還是網路請求策略等各種策略,仍有非常多需要精細化的去最佳化的點,才能讓盡量多的使用者都能獲得更好的播放體驗。
-- END --
進技術交流群, 掃碼添加我的微信:Byte-Flow
獲取相關資料和源碼
學習音視訊、OpenGL ES、Vulkan 、Metal、影像濾鏡、視訊特效及相關渲染技術的付費社群,面試指導,1v1 簡歷服務,職業規劃。
我的付費社群
推薦: