基于MediaPlayer的Android播放器控件

Android自身的播放控件在界面定制上不是很方便,而且沒有針對(duì)播放流進(jìn)行加工處理的相關(guān)接口。于是自己寫了一個(gè)基于MediaPlayer的播放器控件。該控件有以下特點(diǎn):

  1. 支持開發(fā)者對(duì)播放界面進(jìn)行任意的定制。
  2. 支持開發(fā)者對(duì)播放流進(jìn)行加工處理,比如加解密等。
  3. 支持開發(fā)者進(jìn)行插件開發(fā)。
  4. 自帶了三個(gè)插件:外掛字幕插件,圖片廣告插件和彈幕插件

效果圖


橫屏彈幕.png

豎屏播放列表.png

Demo下載

github地址:https://github.com/thfhongfeng/PinePlayer

Demo解析

一、項(xiàng)目結(jié)構(gòu)
項(xiàng)目結(jié)構(gòu).png
二、播放器控件圖層結(jié)構(gòu)
  1. 播放器View圖層結(jié)構(gòu):


    PineMediaPlayerView圖層.png

    最外層為PineMediaPlayerView,由下往上依次為:
    a). 播放器畫面的surfaceview,位于最底層。
    b). PineMediaController View,覆蓋于播放器surfaceview之上。

  2. 播放器控件PineMediaController圖層結(jié)構(gòu):


    PineMediaController圖層.png

    控制器控件界面由下往上依次為:
    a). 背景view,位于PineMediaController底層。
    b). 各類插件View:廣告,外掛字幕,彈幕等,覆蓋于背景View之上。
    c). 內(nèi)置控制器View,覆蓋于插件View之上。
    d). 加載等待View,覆蓋于內(nèi)置控制器View之上。
    e). 右側(cè)View,覆蓋于加載等待View之上。
    具體可參考PineMediaController的attachToParentView方法中添加各個(gè)View的順序。

  3. 播放器插件Plugin View圖層結(jié)構(gòu):


    PluginView圖層.png

    由下往上依次為:
    a). 寬高與播放畫面SurfaceView相同的插件View,比如自帶的外掛字幕插件。


    PluginMatchSurfaceView圖層.png

    b). 寬高與PineMediaController相同的插件View,比如自帶的圖片廣告插件。
    PluginMatchControllerView圖層.png
三、類結(jié)構(gòu)
  1. 組件類圖


    組件類圖.png

    PineSurfaceView為播放畫面的surface view,PineMediaController是控制器界面管理類,管理控制器界面。PineMediaPlayerView則是控件的最外層View,surface view和控制器View都是其子View,其中控制器View 覆蓋在surface view上面。
    a). PineMediaPlayerView,PineMediaController,PineSurfaceView為界面View。
    b). PineMediaPlayerComponent封裝具體的播放器(本項(xiàng)目封裝的是MediaPlayer),通過代理PineMediaPlayerProxy與界面進(jìn)行交互。

  2. 控件適配類圖


    界面適配類圖.png

    開發(fā)者通過實(shí)現(xiàn)PineMediaController.AbstractMediaControllerAdapter來進(jìn)行適配:
    a). onCreateBackgroundViewHolder:背景View定制,返回PineBackgroundViewHolder給播放器控件,該View會(huì)通過attachToParentView加入到控件中。
    b). onCreateInRootControllerViewHolder:內(nèi)置控制器View定制,返回PineControllerViewHolder給播放器控件,該View會(huì)通過attachToParentView加入到控件中。
    c). onCreateOutRootControllerViewHolder:外置控制器View,返回PineControllerViewHolder給播放器控件,該View不會(huì)加入到控件中,而由用戶自己指定顯示的位置,但依然需生成PineControllerViewHolder給播放器,使得播放器播放行為與該View相關(guān)聯(lián)。
    d). onCreateWaitingProgressViewHolder:加載等待View定制,返回PineWaitingProgressViewHolder給播放器控件,該View會(huì)通過attachToParentView加入到控件中。
    e). onCreateRightViewHolderList:全屏下的右側(cè)View定制,返回PineRightViewHolder列表給播放器控件,該View List會(huì)通過attachToParentView加入到控件中(主要應(yīng)用有播放列表View,清晰度列表View等)。
    f). onCreateControllerMonitor:返回界面更新適配器ControllerMonitor。
    g). onCreateControllersActionListener:返回點(diǎn)擊及手勢事件適配器接口IControllersActionListener。
    適配分兩類:
    a). 界面適配:onCreateXXXViewholder
    b). 事件適配,事件適配又分兩類:
    界面更新事件適配-onCreateControllerMonitor;
    點(diǎn)擊及手勢事件適配-onCreateControllersActionListener。

  3. 插件類圖


    插件類圖.png

    插件使得開發(fā)者可以對(duì)控件進(jìn)行界面和功能性的擴(kuò)展。開發(fā)者通過實(shí)現(xiàn)IPinePlayerPlugin接口來定制自己的功能。該接口主要的API
    a). onInit:用于插件初始化。
    b). createViewHolder:插件界面的創(chuàng)建。
    c). getContainerType:插件界面寬高匹配類別,TYPE_MATCH_CONTROLLER-與控制器界面的寬高相同,TYPE_MATCH_SURFACE-與surface view的寬高相同。
    d). onMediaPlayerXXX:播放器播放狀態(tài)回調(diào)。
    e). onTime:播放器播放時(shí)間間隔(每200毫秒回調(diào)一次)回調(diào)。
    f). onRelease:播放器釋放后回調(diào)。

本demo內(nèi)置了三個(gè)插件:外掛字幕插件,圖片廣告插件和彈幕插件,開發(fā)者可以參考這三個(gè)插件來定制自己的插件。

四、常用的API說明
  1. PineMediaPlayerView:
/**
* 播放器控件初始化
* @param mediaPlayerTag   播放器唯一標(biāo)識(shí),如果mediaPlayerTag標(biāo)識(shí)的播放器已經(jīng)初始化,
*                         則將控件綁定到該播放器上,否則初始化一個(gè)新的mediaPlayerTag標(biāo)識(shí)的播放器,
*                         并綁定控件到播放器上。
* @param controller   IPineMediaController 實(shí)例,即播放器控制器
* @param enableSurface   是否需要SurfaceView來呈現(xiàn)播放畫面(默認(rèn)為true),對(duì)于音頻則可以設(shè)置為false
* @param saveMediaStateWhenHide   當(dāng)控件View隱藏時(shí)(比如控件所在Activity被pause,或者失去焦點(diǎn))是否自動(dòng)保存當(dāng)前播放狀態(tài),
*                                 用于再次顯示之后的恢復(fù)到之前的播放狀態(tài)(默認(rèn)為true)。
*/
void init(String mediaPlayerTag, PineMediaWidget.IPineMediaController controller,
                     boolean enableSurface, boolean saveMediaStateWhenHide);

/**
* 獲取播放器控件綁定的播放器接口
*/
PineMediaWidget.IPineMediaPlayer getMediaPlayer()
  1. IPineMediaPlayer
/**
* 開始播放
*/
void start();

/**
* 暫停播放
*/
void pause();

/**
* 恢復(fù)播放
*/
void resume();

/**
* 設(shè)置多媒體播放參數(shù)
*
* @param pineMediaPlayerBean 多媒體播放參數(shù)對(duì)象
*/
void setPlayingMedia(PineMediaPlayerBean pineMediaPlayerBean);

/**
* 保存播放狀態(tài)和進(jìn)度
*/
void savePlayMediaState();

/**
* 設(shè)置是否為獨(dú)立播放模式(是否與播放界面共生命周期)
*
* @param isAutocephalyPlayMode 設(shè)置是否為獨(dú)立播放模式
* @param shouldDestroyWhenDetach   在非獨(dú)立模式下,當(dāng)控件View從上下文環(huán)境中(Context)移除時(shí),
*                            播放器是銷毀(destroy)還是釋放(release)
* true: destroy模式下,從Context中移除后,非獨(dú)立播放器所有狀態(tài)清除,對(duì)象銷毀,無法使用resume來恢復(fù)播放狀態(tài)
* false: release模式下,從Context中移除后,非獨(dú)立播放器所有狀態(tài)清除,對(duì)象不會(huì)銷毀,可以使用resume來恢復(fù)播放狀態(tài)
*/
void setAutocephalyPlayMode(boolean isAutocephalyPlayMode, boolean destroyWhenDetach);

更多API請(qǐng)參考PineMediaWidget.IPineMediaPlayer接口

  1. PineMediaController
/**
* 設(shè)置播放器控制器適配器(自定義自己的播放器控制器界面及顯示方式)
*
* @param adapter 適配器
*/
void setMediaControllerAdapter(AbstractMediaControllerAdapter adapter)
  1. AbstractMediaControllerAdapter
/**
* 適配器初始化
*
* @param player
* @return
*/
protected boolean init(PineMediaWidget.IPineMediaPlayer player) {
    return true;
}

/**
* 背景布局,會(huì)被添加到PineMediaPlayerView布局中,
* 位于PineMediaController View最底層。用于播放切換過程中的背景布置,或者播放音頻時(shí)的背景圖
*
* @param player
* @param isFullScreenMode
* @return
*/
protected abstract PineBackgroundViewHolder onCreateBackgroundViewHolder(
                PineMediaWidget.IPineMediaPlayer player, boolean isFullScreenMode);

/**
* Controller內(nèi)置控件布局的view holder,會(huì)被添加到PineMediaPlayerView布局中,
* 與onCreateOutRootControllerViewHolder互斥,優(yōu)先使用OutRoot布局。
* 覆蓋在BackgroundView上,請(qǐng)使用透明背景
* 需要在該方法中綁定布局的相應(yīng)控件到ViewHolder中,對(duì)應(yīng)的控件功能才能被激活
*
* @param player
* @param isFullScreenMode
* @return
*/
protected abstract PineControllerViewHolder onCreateInRootControllerViewHolder(
                PineMediaWidget.IPineMediaPlayer player, boolean isFullScreenMode);

/**
* Controller外置控件布局的view holder,不會(huì)被添加到PineMediaPlayerView布局中,
* 與onCreateInRootControllerViewHolder互斥,優(yōu)先使用OutRoot布局。
* 需要在該方法中綁定布局的相應(yīng)控件到ViewHolder中,對(duì)應(yīng)的控件功能才能被激活
*
* @param player
* @param isFullScreenMode
* @return
*/
protected abstract PineControllerViewHolder onCreateOutRootControllerViewHolder(
                PineMediaWidget.IPineMediaPlayer player, boolean isFullScreenMode);

/**
* 播放準(zhǔn)備過程中的等待界面的view holder,會(huì)被添加到PineMediaPlayerView布局中,
* 覆蓋在ControllerView上
*
* @param player
* @param isFullScreenMode
* @return
*/
protected abstract PineWaitingProgressViewHolder onCreateWaitingProgressViewHolder(
                PineMediaWidget.IPineMediaPlayer player, boolean isFullScreenMode);

/**
* 內(nèi)置的右側(cè)view holder List,會(huì)被添加到PineMediaPlayerView布局中,
* 覆蓋在WaitingProgressView上
*
* @param player
* @param isFullScreenMode
* @return
*/
protected abstract List<PineRightViewHolder> onCreateRightViewHolderList(
                PineMediaWidget.IPineMediaPlayer player, boolean isFullScreenMode);

/**
* Controller各個(gè)顯示部件及顯示狀態(tài)更新回調(diào)器
*
* @return
*/
protected ControllerMonitor onCreateControllerMonitor() {
    return new ControllerMonitor();
}

/**
* Controller各個(gè)控制部件的事件的listener
*
* @return
*/
protected ControllersActionListener onCreateControllersActionListener() {
    return new ControllersActionListener();
}

/**
* 設(shè)置當(dāng)前播放媒體在播放列表中的位置
*
* @param position
*/
public void setCurrentMediaPosition(int position) {

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容