1. 程式人生 > 實用技巧 >04.視訊播放器通用架構實踐

04.視訊播放器通用架構實踐

04.視訊播放器通用架構實踐

目錄介紹

  • 01.視訊播放器的痛點
  • 02.業務需求的目標
  • 03.該播放器框架特點
  • 04.播放器核心封裝
  • 05.播放器UI層封裝
  • 06.如何簡單使用
  • 07.如何自定義播放器
  • 08.該案例的拓展性分享
  • 09.關於視訊快取方案
  • 10.如何監控視訊埋點
  • 11.待實現的需求分析
  • 12.一些細節上優化
  • 13.參考案例和部落格記錄

00.視訊播放器通用框架

  • 基礎封裝視訊播放器player,可以在ExoPlayer、MediaPlayer,聲網RTC視訊播放器核心,原生MediaPlayer可以自由切換
  • 對於檢視狀態切換和後期維護拓展,避免功能和業務出現耦合。比如需要支援播放器UI高度定製,而不是該lib庫中UI程式碼
  • 針對視訊播放,音訊播放,播放回放,以及視訊直播的功能。使用簡單,程式碼拓展性強,封裝性好,主要是和業務徹底解耦,暴露介面監聽給開發者處理業務具體邏輯
  • 該播放器整體架構:播放器核心(自由切換) + 視訊播放器 + 邊播邊快取 + 高度定製播放器UI檢視層
  • 專案地址:github.com/yangchong21…
  • 關於視訊播放器整體功能介紹文件:juejin.im/post/688345…
  • 關於視訊播放器通用架構實踐:juejin.im/post/688417…

01.視訊播放器的痛點

  • 播放器核心難以切換
    • 不同的視訊播放器核心,由於api不一樣,所以難以切換操作。要是想相容核心切換,就必須自己制定一個視訊介面+實現類的播放器
  • 播放器核心和UI層耦合
    • 也就是說視訊player和ui操作柔和到了一起,尤其是兩者之間的互動。比如播放中需要更新UI進度條,播放異常需要顯示異常UI,都比較難處理播放器狀態變化更新UI操作
  • UI難以自定義或者修改麻煩
    • 比如常見的視訊播放器,會把視訊各種檢視寫到xml中,這種方式在後期程式碼會很大,而且改動一個小的佈局,則會影響大。這樣到後期往往只敢加程式碼,而不敢刪除程式碼……
    • 有時候難以適應新的場景,比如新增一個播放廣告,老師開課,或者視訊引導業務需求,則需要到播放器中寫一堆業務程式碼。迭代到後期,違背了開閉原則,視訊播放器需要做到和業務分離
  • 視訊播放器結構不清晰
    • 這個是指該視訊播放器能否看了文件後快速上手,知道封裝的大概流程。方便後期他人修改和維護,因此需要將視訊播放器功能分離。比如切換核心+視訊播放器(player+controller+view)
  • 播放器播放和業務耦合
    • 比如多個app共用一個視訊播放器元件,一個播放業務播放器狀態發生變化,其他播放業務必須同步更新播放狀態,各個播放業務之間互相交叉,隨著播放業務的增多,開發和維護成本會急劇增加, 導致後續開發不可持續。

02.業務需求的目標

  • 常見的業務需求
    • 基礎封裝視訊播放器player,可以在ExoPlayer、MediaPlayer,聲網RTC視訊播放器核心,原生MediaPlayer可以自由切換
    • 對於檢視狀態切換和後期維護拓展,避免功能和業務出現耦合。比如需要支援播放器UI高度定製,而不是該lib庫中UI程式碼
    • 針對視訊播放,音訊播放,播放回放,以及視訊直播的功能。使用簡單,程式碼拓展性強,封裝性好,主要是和業務徹底解耦,暴露介面監聽給開發者處理業務具體邏輯
  • 音視訊播放框架
    • 視訊播放等於MediaPlayer和SurfaceView,MediaPlayer主要用於播放音訊,沒有提供影象輸出介面,所以我們需要藉助其他的元件來顯示MediaPlayer播放的影象輸出,我們可以使用SurfaceView來顯示
    • 能否實踐開發出一套音視訊播放的通用架構,能支援音訊播放場景,也能播放視訊場景,還可以無縫切換。比如視訊切換音訊操作,增強庫的功能性
    • 視訊視窗、音訊視窗、視訊浮窗、音訊浮窗、短視訊視窗、短視訊浮窗、音訊控制檯等多種場景播放,需要靈活切換,這個也是一個大的難點

03.該播放器框架特點

  • 一定要解耦合
    • 播放器核心與播放器解耦: 支援更多的播放場景、以及新的播放業務快速接入,並且不影響其他播放業務,比如後期新增阿里雲播放器核心,或者騰訊播放器核心
    • 播放器player與視訊UI解耦:支援新增自定義視訊檢視,比如支援新增自定義廣告,新手引導,或者視訊播放異常等檢視,這個需要較強的拓展性
  • 適合多種業務場景
    • 比如適合播放單個視訊,多個視訊,以及列表視訊,或者類似抖音那種一個頁面一個視訊,還有小視窗播放視訊。也就是適合大多數業務場景
  • 播放器的整體層級圖
  • 播放器架構的介紹
    • 基礎核心播放庫:提供基礎的播放功能,可以自由切換核心,也方便拓展新增其他sdk核心播放器
    • 統一播放器:遮蔽底層核心播放器播放差異,根據協議為上層提供統一的播放能力介面,供上層呼叫
    • 播放檢視層:負責播放器檢視層的UI控制和排程,徹底解除播放業務與播放器的耦合
    • 播放場景業務:負責向用戶展示音視訊播放能力和互動的業務
    • 播放關聯業務: 為播放器提供增值或支撐的業務,比如視訊埋點統計,後期新增投屏,後期新增下載功能
    • demo:提供各種播放場景案例程式碼,基本上有大多數常用播放器的使用場景,建議直接看demo拿來即用

04.播放器核心封裝

4.0 遇到的問題

  • 播放器核心拓展難
    • 不同的播放SDK提供的API都不一樣,如果業務層對每個合作方都進行業務開發,就會導致業務量非常龐大,並且不同合作的方的播放SDK會產生交叉,不利於播放業務的維護和拓展。
  • 播放器核心難以切換
    • 不同的視訊播放器核心,由於api不一樣,所以難以切換操作。要是想相容核心切換,就必須自己制定一個視訊介面+實現類的播放器

4.1 視訊播放器核心封裝需求

  • 一定要解耦合
    • 播放器核心與播放器解耦: 支援更多的播放場景、以及新的播放業務快速接入,並且不影響其他播放業務,比如後期新增阿里雲播放器核心,或者騰訊播放器核心
  • 傳入不同型別方便建立不同核心
    • 隱藏核心播放器建立具體細節,開發者只需要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體播放器類的類名。需要符合開閉原則
  • 具體設計方案
    • 設計統一播放協議,對於上層播放業務,只調用按照統一協議設計介面,不必關心底層播放器的設計邏輯。保證上層播放業務不隨新的接入播放SDK發生變化。

4.2 播放器核心架構圖

  • 播放器核心架構圖
  • 播放器核心程式碼說明

4.3 如何相容不同核心播放器

  • 提問:針對不同核心播放器,比如谷歌的ExoPlayer,B站的IjkPlayer,還有原生的MediaPlayer,有些api不一樣,那使用的時候如何統一api呢?
    • 比如說,ijk和exo的視訊播放listener監聽api就完全不同,這個時候需要做相容處理
    • 定義介面,然後各個不同核心播放器實現介面,重寫抽象方法。呼叫的時候,獲取介面物件呼叫api,這樣就可以統一Api
  • 播放器核心
    • 可以切換ExoPlayer、MediaPlayer,IjkPlayer,聲網視訊播放器,這裡使用工廠模式Factory + AbstractVideoPlayer + 各個實現AbstractVideoPlayer抽象類的播放器類
    • 定義抽象的播放器,主要包含視訊初始化,設定,狀態設定,以及播放監聽。由於每個核心播放器api可能不一樣,所以這裡需要實現AbstractVideoPlayer抽象類的播放器類,方便後期統一呼叫
    • 為了方便建立不同核心player,所以需要建立一個PlayerFactory,定義一個createPlayer建立播放器的抽象方法,然後各個核心都實現它,各自建立自己的播放器
  • 關於AbstractVideoPlayer介面詳細說明。這個介面定義通用視訊播放器方法,比如常見的有:視訊初始化,設定url,載入,以及播放狀態,簡單來說可以分為三個部分。
    • 第一部分:視訊初始化例項物件方法,主要包括:initPlayer初始化視訊,setDataSource設定視訊播放器地址,setSurface設定視訊播放器渲染view,prepareAsync開始準備播放操作
    • 第二部分:視訊播放器狀態方法,主要包括:播放,暫停,恢復,重製,設定進度,釋放資源,獲取進度,設定速度,設定音量
    • 第三部分:player繫結view後,需要監聽播放狀態,比如播放異常,播放完成,播放準備,播放size變化,還有播放準備
  • 播放器的核心實現要點
    • 針對上層播放器業務,該核心庫提供統一的播放暫停,設定播放狀態的介面,由於播放器核心和播放器業務解耦合,所以非常方便快速新增其他sdk播放器,具體可以看這篇文章:05.視訊播放器核心切換封裝

05.播放器UI層封裝

5.1 實際開發遇到問題

  • 發展中遇到的問題
    • 播放器可支援多種場景下的播放,多個產品會用到同一個播放器,這樣就會帶來一個問題,一個播放業務播放器狀態發生變化,其他播放業務必須同步更新播放狀態,各個播放業務之間互相交叉,隨著播放業務的增多,開發和維護成本會急劇增加, 導致後續開發不可持續。
  • 不太好適合多種業務場景
    • 比如適合播放單個視訊,多個視訊,以及列表視訊,或者類似抖音那種一個頁面一個視訊,還有小視窗播放視訊。也就是適合大多數業務場景,視訊通用性需要儘可能完善

5.2 如何分離播放和UI分離

  • VideoPlayer播放器
    • 可以自由切換視訊核心,Player+Controller。player負責播放的邏輯,Controller負責檢視相關的邏輯,兩者之間用介面進行通訊
    • 針對Controller,需要定義一個介面,主要負責檢視UI處理邏輯,支援新增各種自定義檢視View【統一實現自定義介面Control】,每個view儘量保證功能單一性,最後通過addView形式新增進來
    • 針對Player,需要定義一個介面,主要負責視訊播放處理邏輯,比如視訊播放,暫停,設定播放進度,設定視訊連結,切換播放模式等操作。需要注意把Controller設定到Player裡面,兩者之間通過介面互動
  • UI控制器檢視
    • 定義一個BaseVideoController類,這個主要是整合各種事件的處理邏輯,比如播放器狀態改變,控制檢視隱藏和顯示,播放進度改變,鎖定狀態改變,裝置方向監聽等等操作
    • 定義一個view的介面InterControlView,在這裡類裡定義繫結檢視,檢視隱藏和顯示,播放狀態,播放模式,播放進度,鎖屏等操作。這個每個實現類則都可以拿到這些屬性呢
    • 在BaseVideoController中使用LinkedHashMap儲存每個自定義view檢視,新增則put進來後然後通過addView將檢視新增到該控制器中,這樣非常方便新增自定義檢視
    • 播放器切換狀態需要改變Controller檢視,比如視訊異常則需要顯示異常檢視view,則它們之間的互動是通過ControlWrapper(同時實現Controller介面和Player介面)實現
  • 具體如何實現呢

5.3 關於優先順序檢視展示

  • 視訊播放器為了拓展性,需要暴露view介面供外部開發者自定義視訊播放器檢視,通過addView的形式新增到播放器的控制器中。
    • 這就涉及view檢視的層級性。控制view檢視的顯示和隱藏是特別重要的,這個時候在自定義view中就需要拿到播放器的狀態
  • 舉一個簡單的例子,基礎視訊播放器
    • 添加了基礎播放功能的幾個播放檢視。有播放完成,播放異常,播放載入,頂部標題欄,底部控制條欄,鎖屏,以及手勢滑動欄。如何控制它們的顯示隱藏切換呢?
    • 在addView這些檢視時,大多數的view都是預設GONE隱藏的。比如當視訊初始化時,先緩衝則顯示緩衝view而隱藏其他檢視,接著播放則顯示頂部/底部檢視而隱藏其他檢視
  • 比如有時候需要顯示兩種不同的自定義檢視如何處理
    • 舉個例子,播放的時候,點選一下視訊,會顯示頂部title檢視和底部控制條檢視,那麼這樣會同時顯示兩個檢視。
    • 點選頂部title檢視的返回鍵可以關閉播放器,點選底部控制條檢視的播放暫停可以控制播放條件。這個時候底部控制條檢視FrameLayout的ChildView在整個視訊的底部,頂部title檢視FrameLayout的ChildView在整個視訊的頂部,這樣可以達到上下層都可以相應事件。
  • 那麼FrameLayout層層重疊,如何讓下層不響應事件
    • 在最上方顯示的層加上: android:clickable="true" 可以避免點選上層觸發底層。或者直接給控制設定一個background顏色也可以。

5.4 視訊播放器重力感應監聽

  • 區別視訊幾種不同的播放模式
    • 正常播放時,設定檢查系統是否開啟自動旋轉,開啟監聽;全屏模式播放視訊的時候,強制監聽裝置方向;在小視窗模式播放視訊的時候,取消重力感應監聽
    • 注意一點。關於是否開啟自動旋轉的重力感應監聽,可以給外部開發者暴露一個方法設定的開關。讓使用者選擇是否開啟該功能
  • 具體怎麼操作
    • 寫一個類,然後繼承OrientationEventListener類,注意視訊播放器重力感應監聽不要那麼頻繁。表示500毫秒才檢測一次……
    • mOrientationHelper.enable();表示檢查系統是否開啟自動旋轉。mOrientationHelper.disable();表示取消監聽
    • 具體可以看這篇部落格:06.播放器UI抽取封裝

06.如何簡單使用

6.1 播放單個視訊

  • 必須需要的四步驟程式碼如下所示
    //建立基礎視訊播放器,一般播放器的功能
    BasisVideoController controller = new BasisVideoController(this);
    //設定控制器
    mVideoPlayer.setVideoController(controller);
    //設定視訊播放連結地址
    mVideoPlayer.setUrl(url);
    //開始播放
    mVideoPlayer.start();
    複製程式碼
  • 只需要四步操作即可,非常簡單。這樣就可以滿足一個基礎的視訊播放器
    • 具體邏輯可以看:BasisVideoController
  • 如何新增只定義檢視,非常方便。AdControlView需要實現InterControlView接口才可以
    AdControlView adControlView = new AdControlView(this);
    controller.addControlComponent(adControlView);
    複製程式碼
  • 要是一個頁面播放多個視訊怎麼辦
    • 直接建立兩個VideoPlayer,實現程式碼和播放單個視訊一樣,只是需要注意:不要開啟音訊焦點監聽。
    • 如果是開啟的音訊焦點改變監聽,那麼播放該視訊的時候,就會停止其他音視訊的播放操作。類似,你聽音樂,這個時候去看視訊,那麼音樂就暫停呢

6.2 列表播放視訊

  • 關於列表播放視訊,該案例支援
    • 列表頁面有多個item
      • 第一種:點選item播放,當item滑動到不可見時暫停播放;點選其他可見item播放視訊,則會暫停其他正在播放的視訊,也就是說一次只能播放一個視訊
      • 第二種:滑動item,使用者不用點選,讓其自動進行播放,這種業務場景在玩手機碰到過。大概思路時,進入列表自動播放第一個,然後在RecyclerView滑動監聽的方法中,判斷如果頁面滑動停止了,則遍歷RecyclerView子控制元件找到第一個完全可見的item,然後拿到該item的索引即可播放該位置的視訊
    • 列表頁面是一個頁面一個item
      • 第一種操作使用ViewPager,是垂直方向可以滾動的VerticalViewPager + PagerAdapter,這種方式在item建立上可以設定預載入載入佈局檢視
      • 第二種操作使用RecyclerView,是用ScrollPageHelper + RecyclerView,這種方式也可以實現一個頁面一個item,一次滑動一個
  • 如何保證在列表中只播放一個視訊。兩種方案
    • 第一種:每個item放一個VideoPlayer,但是要注意需要用一個單例VideoPlayerManager來保證只有一個VideoPlayer物件,這樣就可以保證一次播放一個視訊。當ViewHolder中的檢視被回收時需要銷燬視訊資源
    • 第二種:只建立一個VideoPlayer,那個播放就新增到具體的item佈局中。比如播放第一個視訊就把player物件新增到檢視中,點選播放第三個時需要把player從它的父佈局中移除後然後再新增到該item的佈局中,這樣就可以實現
  • list條目中滑動item不可見就停止視訊播放
    • 在列表中播放,可以監聽RecyclerView中的item生命週期,有一個AttachedToWindow是繫結item檢視,還有一個DetachedFromWindow方法是item離開視窗時呼叫,在這個裡面可以做視訊銷燬的邏輯。

07.如何自定義播放器

  • BasisVideoController已經滿足基礎視訊播放器功能
    • 在該控制器中,已經做了相關的初始化操作,比如設定視訊可以拖動,根據螢幕方向自動進入/退出全屏,設定滑動調節亮度,音量,進度,預設開啟等操作。
    • 快速新增基礎視訊播放器的模組,包括視訊播放完成view,播放異常view,播放top檢視view,播放底部控制藍view,手勢滑動檢視view等。同時在每一個檢視view中可以拿到視訊播放器的狀態,便於設定UI的操作。
  • 比如在此播放器基礎上,新增廣告檢視view
    • 現在有個業務需求,需要在視訊播放器剛開始新增一個廣告檢視,等待廣告倒計時120秒後,直接進入播放視訊邏輯。相信這個業務場景很常見,大家都碰到過,使用該播放器就特別簡單。
    • 首先建立一個自定義view,需要實現InterControlView介面,重寫該介面中所有抽象方法,這裡省略了很多程式碼,具體看demo。最後在呼叫controller.addControlComponent(adControlView);新增到基礎視訊播放器,這種方式滿足大多數的場景……
  • 那要是基礎播放器不滿足UI該怎麼辦?
    • 好辦,直接仿照BasisVideoController建立一個你自己的控制器,ui想怎麼定製你自己決定。比如說你要實現一個小視窗播放視訊,那這個時候肯定需要定製,照葫蘆畫瓢,具體可以看CustomFloatController類。

08.該案例的拓展性分享

  • 可以配置多個核心切換
    • 只需要你在配置的時候,傳入不同的型別即可建立不同的播放器核心,十分方便。如果後期你要拓展其他的核心播放器,只需要按照exo的程式碼案例弄一套即可,十分方便,加入其他核心播放器不會影響到你的業務。
      PlayerFactory player = PlayerFactoryUtils.getPlayer(PlayerConstant.PlayerType.TYPE_IJK);
      複製程式碼
  • 可以配置統一視訊埋點監聽
    • 避免在每個帶有視訊的頁面activity或者Fragment中新增埋點,而是有播放器框架內部提供一個埋點的介面,外部開發者只需要實現這個介面即可全域性埋點視訊播放器,非常方便和管理維護,針對介面增加或者刪除都是不影響你其他的業務。
  • 開發者可以自由新增自定義視訊檢視
    • 在封裝BaseVideoController控制器的時候,考慮到後期的拓展性,把視訊各個視訊都是以addView的形式新增進來,使用LinkedHashMap儲存這樣可以保證順序。
    • 需要注意的是在這個Controller中,需要把播放器的播放狀態,播放模式,播放進度,鎖屏等操作給繫結到開發者自定義實現的播放器檢視View中。
  • 暴露眾多視訊操作的方法給開發者
    • 比如給視訊設定封面圖片,這個時候總不能在播放器內部引入一個Glide,然後載入圖片,這樣和業務耦合呢。可以把這個設定封面view暴露給開發者,然後設定,這樣更好一些。
    • 比如外部開發者想要知道視訊播放器的狀態,做一些業務上操作,這個時候完全可以通過介面的形式暴露出來,該播放器把視訊的播放模式監聽,播放狀態監聽,還有各種視訊操作都暴露了方法出來,方便開發者呼叫。

09.關於視訊快取方案

  • 網路上比較好的專案:github.com/danikula/An…
    • 網路用的HttpURLConnection,檔案快取處理,檔案最大限度策略,回撥監聽處理,斷點續傳,代理服務等。
  • 但是存在一些問題,比如如下所示
    • 檔案的快取超過限制後沒有按照lru演算法刪除,
    • 處理返回給播放器的http響應頭訊息,響應頭訊息的獲取處理改為head請求(需伺服器支援)
    • 替換網路庫為okHttp(因為大部分的專案都是以okHttp為網路請求庫的),但是這個改動性比較大
  • 然後看一下怎麼使用,超級簡單。傳入視訊url連結,返回一個代理連結,然後就可以呢
    HttpProxyCacheServer server = new HttpProxyCacheServer(this);
    String proxyVideoUrl = server.getProxyUrl(URL_AD);
    複製程式碼
  • 大概的原理
    • 原始的方式是直接塞播放地址給播放器,它就可以直接播放。現在我們要在中間加一層本地代理,播放器播放的時候(獲取資料)是通過我們的本地代理的地址來播放的,這樣我們就可以很好的在中間層(本地代理層)做一些處理,比如:檔案快取,預快取(秒開處理),監控等。
  • 原理詳細一點來說
  • 如何實現預載入
    • 其實預載入的思路很簡單,在進行一個播放視訊後,再返回接下來需要預載入的視訊url,啟用執行緒去請求下載資料
    • 開啟一個執行緒去請求並預載入一部分的資料,可能需要預載入的資料大於>1,利用佇列先進入的先進行載入,因此可以採用LinkedHashMap儲存正在預載入的task。
    • 在開始預載入的時候,判斷該播放地址是否已經預載入,如果不是那麼建立一個執行緒task,並且把它放到map集合中。然後執行預載入邏輯,也就是執行HttpURLConnection請求
    • 提供取消對應url載入的任務,因為有可能該url不需要再進行預載入了,比如參考抖音,當用戶瞬間下滑幾個視訊,那麼很多視訊就需要跳過了不需要再進行預載入。這個後期在做

10.如何監控視訊埋點

  • 傳統一點的做法
    • 比如用友盟或者百度統計,或者用其他的統計。之前的做法是,在每個有視訊的頁面比如說Activity,Fragment等開啟時視訊播放時埋點一次,頁面退出時埋點一次。
    • 如果app中有多個activity或者fragment頁面,那麼就每個頁面都要進行埋點。比如如果你的app是付費視訊,你想知道有多少人試看了,該怎麼操作。那麼你需要在每一個有視訊的activity頁面挨個新增埋點,那還有沒有更好的辦法?
  • 解決方案
    • 舉個例子:例如,你需要來讓外部開發者手動去埋點,可是在類中怎麼埋點又是由其他人來設計的,你只是需要對外暴露監聽的方法。那麼該如何做呢?採用介面 + 實現類方式即可實現。
  • 該案例中怎麼操作
    • 定義一個介面,規定其他人設計類,必須繼承這個介面。在這個介面中,定義進入視訊播放,退出視訊播放器,記錄播放進度,視訊播放完成,播放異常,點選廣告,點選試看等操作的抽象方法。具體可以看BuriedPointEvent類程式碼……
  • 外部開發者如何使用
    • 定義一個類實現該視訊埋點介面,重寫裡面方法。然後需要在初始化配置視訊播放器的時候,將這個實現類的物件傳遞進來即可。通過這個配置類傳進來的物件,播放器就可以處理監聽設定邏輯呢。
    • 這種操作最大的好處就是:在這個類中統一處理視訊的埋點,修改快捷,而不用在每一個有視訊播放器的頁面埋點,方便維護。比如如何處理視訊播放完成監聽,程式碼如下所示:
      @Override
      public void onCompletion() {
          VideoPlayerConfig config = VideoViewManager.getConfig();
          if (config!=null && config.mBuriedPointEvent!=null){
              //視訊播放完成
              config.mBuriedPointEvent.playerCompletion(mUrl);
          }
      }
      複製程式碼

11.待實現的需求分析

  • 音視訊無縫切換
    • 比如在豆神教育中,有視訊播放,也有音訊播放,這兩塊都是寫到了業務程式碼中,能否將兩者糅合起來。但音訊相比視訊,多了一個可以在後臺播放的功能,一般用在service中,這一相互切換需求待完善。以滿足後期可能出現的需求功能。
  • 優化播放器持續平滑播放
    • 畫中畫方案:雖然Android8.0及其以上版本已提供了畫中畫方案,但是Android8.0以下版本仍然保有大量使用者,其缺點就是無法滿足Android8.0以下使用者需;
    • 採用系統浮層:採用系統浮層需要系統浮層許可權,Android廠商對系統浮層的授權越來越嚴格,導致使用者授權過程的體驗比較差;需要許可權,可能有些手機不太好適配;
    • 在每個展示頁面單獨新增播放器浮窗:優點是不受Android系統版本限制,並且使用者無需系統浮層許可權授權,適合所有手機使用者,體驗較好

12.一些細節上優化

  • 多使用註解限定符
    • 對於一些關於型別的方法引數,可以多用註解限定符,暴露給外部開發者呼叫的方法,可以防止傳入正確的型別。比如:PlayerFactoryUtils.getPlayer(PlayerConstant.PlayerType.TYPE_IJK)
  • 完善的api文件
    • api文件充分完善到每一個細節,以及配套demo,方便快速上手。完善的程式碼註釋,以及專案的類結構圖,方便快速瞭解視訊播放器的整體輪廓
  • 豐富的demo案例
    • 提供絕大多數場景的視訊播放器功能,完全可以套用demo中的案例,甚至你還可以在案例基礎上大幅度優化

13.參考案例和部落格記錄

專案地址:github.com/yangchong21…


作者:楊充
連結:https://juejin.im/post/6884170166863986695
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。