天天看點

如何實作 Android 短視訊跨頁面的流暢續播?

在一切皆可視訊化的今天,短視訊内容作為移動端産品新的促活點,受到了越來越多的重視與投入,同時短視訊也是增加使用者粘性、增加使用者停留時長的一把利器。那麼如何快速實作移動端短視訊功能呢?前兩篇我們介紹了盒馬短視訊秒播優化(iOS 篇 / Android 篇),本篇我們聊聊秒播之外,另一個從體感上增加短視訊使用者體驗的能力 - 續播。

作者|少陽

審校|泰一

短視訊作為内容重要的承載方式,是吸引使用者的重點,短視訊的内容與體驗直接關系到使用者是否願意長時停留。是以,體驗的優化就顯得尤為重要。

如何實作 Android 短視訊跨頁面的流暢續播?

跨頁面續播是除秒播外另一個可以從體感上增加使用者體驗的能力。由于一些業務場景需要在不同頁面上播放同一個視訊内容的場景,而這些場景頁面切換往往是連續的,這就要求短視訊的播放也是連續。這樣才能使得體驗上會有連貫性,讓使用者在進入沉浸式頁面時,能流暢的過度,并無感覺的繼續播放,進而産生連續不間斷的感受。

在優化前,盒馬沉浸式短視訊播放頁面的體驗與主流短視訊 App 有明顯差距。從卡片清單頁面跳轉視訊沉浸式頁面時,相同視訊無法續播,影響使用者觀賞和體驗。下面主要介紹盒馬短視訊從普通展示頁進入沉浸式頁面時跨頁面續播能力和流暢的動畫切換效果的實作過程。

手機:Pixel 4

os:Android 10

播放器:淘寶播放器

首先我們來看一下盒馬優化前後與主流短視訊 App 的效果對比

https://v.youku.com/v_show/id_XNTgwNDIwOTM1Ng==.html

從對比可以看出,續播的關鍵在于視訊流的複用以及頁面轉場動畫。

要解決流的複用,同時又要保證進入新的頁面時可以立即播放,不産生聲音和畫面的頓挫,這裡根據上一篇《揭秘盒馬鮮生 APP Android 短視訊秒播優化方案》的分析,必須要解決視訊下載下傳,加載解碼的耗時。

根據《揭秘盒馬鮮生 APP Android 短視訊秒播優化方案》裡講到緩存原理,這裡可以利用播放器播放同一個視訊(注意統一 URL,盒馬全部轉為 H.265)來避免多次下載下傳。

加載解碼的耗時則需要播放器複用來解決。這裡涉及到實作方案,可參照下一章的續播方案選型。

轉場動畫能顯著提高體感流暢度,但實作過程中需要考慮各種相容問題。

在優化前期,我們考慮了三種續播方案。

播放器 View 跨頁面傳遞

優點:思路簡單,體驗效果好。

缺點:業務侵入嚴重,不具通用性,播放器業務回調無法隔離,不利于續播放器管控。

基于 Surface (View) 級别的全局播放器管理

優點:體驗效果好,能擴充記憶體管控,侵入性低。

缺點:實作複雜,需要改寫底層 HMVideoView 的封裝邏輯;改造中易出現記憶體洩漏,較難排查。

基于 MediaPlayer 級别的全局播放器管理

優點:無侵入,能擴充記憶體管控,實作快(可複用和擴充淘寶播放器底層 token 機制)

缺點:需要一定的改造,體驗比方案 1、2 略差(聲音有一瞬間的頓挫,不明顯)

盒馬最終選擇方案 3,這裡方案 2 和 3 原理是相同的,沒有明顯的優劣之分,最終選擇方案 3 是因為這是目前穩定性最高,成本最低的方法。後續的播放器續播、複用、管理的分析同樣适用于方案 2。

業務上,我們需要實作續播,通過問題分析,我們已經知道,通過視訊流的複用即可實作,而視訊流的複用這裡選擇通過複用 MediaPlayer 實作(也可以複用 Surface+MediaPlayer)。

将 MediaPlayer 從 TaobaoPlayerView 中拆解出來,通過 MediaPlayerManager 進行全局管理。全局管理後,所有的播放器的 MediaPlayer 都由 MediaPlayerManager 配置設定和控制。

如何實作 Android 短視訊跨頁面的流暢續播?

各組建間關系

確定業務流程中,隻需要關心業務與 VideoView 之間的互動,底層播放器複用由 MediaPlayerManager 實作。

如何實作 Android 短視訊跨頁面的流暢續播?

播放器複用是管理的一個子集,是以這裡一起介紹。主要原來有以下幾個原則:

全局播放器(MediaPlayer)控制最多建立 4 個。

超過 4 個播放器,建立第 5 個時,先銷毀最少使用的播放器的 MediaPlayer。

每個播放器随機配置設定一個 token(時間戳 + 随機數),也可以開發者指定。

相同 token 的播放器,共享 MediaPlayer。

一個 MediaPlayer 同時隻能被 1 個播放器 Surface 所綁定和持有。

存在相同 token 的播放器,目前播放器在銷毀時,保留 MediaPlayer 執行個體。

已建立的播放器恢複播放,但 MediaPlayer 被其他後建立的播放器占用時,解綁 MediaPlayer 并重新綁定目前播放器。

場景一:APP 共建立 4 個及以内播放器。

如何實作 Android 短視訊跨頁面的流暢續播?

場景二:建立超過 4 個播放器時。

如何實作 Android 短視訊跨頁面的流暢續播?

場景三:新建立的播放器 token 已存在時,複用 MediaPlayer。

如何實作 Android 短視訊跨頁面的流暢續播?

場景四:存在 token 與目前即将被銷毀的播放器 token 一緻時(或已被解除 MediaPlayer 的播放器播放時)。

如何實作 Android 短視訊跨頁面的流暢續播?

邏輯流程圖

從場景總結,MediaPlayer 主要提供 複用、恢複、銷毀、驅逐(建立) 四個能力。

目前轉場動畫有兩個方案可選:

Android 自帶的元素動畫

優點:動畫流暢順滑,無需實作動畫邏輯,由系統自己實作。

缺點:侵入嚴重,需要改寫 Nav 層,在 View 複用的方案下有白屏和黑屏。

自定義實作屬性動畫

優點:侵入小,隻需要前置頁極少的坐标資訊,如果是 View 複用方案,甚至不需要前置頁提供坐标資訊;相容性好,适用于各種播放器複用場景。

缺點:需要自己實作動畫,有一定的閃爍感。

前置頁跳轉到沉浸式,傳遞播放器坐标 Rect 資訊。

沉浸式預設透明,并根據 Rect 坐标資訊建立播放器(複用)。

開始動畫,将播放器 View 放大至正确位置,同時背景不透明度增加。

(注意:這裡最後要将沉浸式頁的主題設為不透明,否則前置頁不會執行 onStop () 具體參考下一節,生命周期填坑。)

ps:傳回動畫同理,過程相反即可。

如何實作 Android 短視訊跨頁面的流暢續播?

屬性動畫原理存在一個坑。

問題描述:

假設頁面為 A->B,方案 3 要求 B 頁面在動畫過程中是全透明的。當 B 的 theme 中 windowIsTranslucent 為 true 時,A->B 過程 A 的生命周期無法走向 stop(即便 B 頁面動畫結束,完全遮蓋 A 頁面)。是以,A 的生命周期沒有按照預期執行,一些需要 onStop 執行的場景下,業務就無法正常執行

B Ativity 的樣式(注:示例代碼):

解決方案:

進入動畫結束時,通過反射調用 Activity 的 convertFromTranslucent 方法, 使 activity 不透明。

傳回動畫開始時,通過反射調用 Activity 的 convertToTranslucent 方法,使 activity 透明。

關于多媒體的優化工作還有很多可以做。除了續播和沉浸式秒播等場景外,我們還可以:

**1. 對播放器的一般性場景進行秒播優化,如首頁清單的卡片視訊。

對播放器的全局執行個體管控,控制播放器建立數量,進而優化記憶體。**

未優化:

操作:連續開啟 30~50 個頁面及播放器。

現象:記憶體飙升,手機發燙,影響手機正常使用。

如何實作 Android 短視訊跨頁面的流暢續播?

優化後:

操作:每秒開啟 1 個頁面和播放器,連續開啟 100 個。

現象:記憶體呈鋸齒狀正常上升,無明顯飙升現象,軟體運作正常。

如何實作 Android 短視訊跨頁面的流暢續播?

下一期我們将繼續分享盒馬 iOS 端短視訊續播的體驗優化實踐。

「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。公衆号背景回複【技術】可加入阿裡雲視訊雲産品技術交流群,和業内大咖一起探讨音視訊技術,擷取更多行業最新資訊。