基于MediaPlayer的Android播放器控件

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

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

效果圖


橫屏彈幕.png

豎屏播放列表.png

Demo下載

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

Demo解析

一齐媒、項目結(jié)構(gòu)
項目結(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方法中添加各個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封裝具體的播放器(本項目封裝的是MediaPlayer)赞别,通過代理PineMediaPlayerProxy與界面進行交互。

  2. 控件適配類圖


    界面適配類圖.png

    開發(fā)者通過實現(xiàn)PineMediaController.AbstractMediaControllerAdapter來進行適配:
    a). onCreateBackgroundViewHolder:背景View定制配乓,返回PineBackgroundViewHolder給播放器控件仿滔,該View會通過attachToParentView加入到控件中。
    b). onCreateInRootControllerViewHolder:內(nèi)置控制器View定制犹芹,返回PineControllerViewHolder給播放器控件堤撵,該View會通過attachToParentView加入到控件中。
    c). onCreateOutRootControllerViewHolder:外置控制器View羽莺,返回PineControllerViewHolder給播放器控件实昨,該View不會加入到控件中,而由用戶自己指定顯示的位置盐固,但依然需生成PineControllerViewHolder給播放器荒给,使得播放器播放行為與該View相關(guān)聯(lián)。
    d). onCreateWaitingProgressViewHolder:加載等待View定制刁卜,返回PineWaitingProgressViewHolder給播放器控件志电,該View會通過attachToParentView加入到控件中。
    e). onCreateRightViewHolderList:全屏下的右側(cè)View定制蛔趴,返回PineRightViewHolder列表給播放器控件挑辆,該View List會通過attachToParentView加入到控件中(主要應(yīng)用有播放列表View,清晰度列表View等)孝情。
    f). onCreateControllerMonitor:返回界面更新適配器ControllerMonitor鱼蝉。
    g). onCreateControllersActionListener:返回點擊及手勢事件適配器接口IControllersActionListener。
    適配分兩類:
    a). 界面適配:onCreateXXXViewholder
    b). 事件適配箫荡,事件適配又分兩類:
    界面更新事件適配-onCreateControllerMonitor魁亦;
    點擊及手勢事件適配-onCreateControllersActionListener。

  3. 插件類圖


    插件類圖.png

    插件使得開發(fā)者可以對控件進行界面和功能性的擴展羔挡。開發(fā)者通過實現(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:播放器播放時間間隔(每200毫秒回調(diào)一次)回調(diào)被冒。
    f). onRelease:播放器釋放后回調(diào)。

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

四肠虽、常用的API說明
  1. PineMediaPlayerView:
/**
* 播放器控件初始化
* @param mediaPlayerTag   播放器唯一標識,如果mediaPlayerTag標識的播放器已經(jīng)初始化玛追,
*                         則將控件綁定到該播放器上税课,否則初始化一個新的mediaPlayerTag標識的播放器,
*                         并綁定控件到播放器上痊剖。
* @param controller   IPineMediaController 實例韩玩,即播放器控制器
* @param enableSurface   是否需要SurfaceView來呈現(xiàn)播放畫面(默認為true),對于音頻則可以設(shè)置為false
* @param saveMediaStateWhenHide   當(dāng)控件View隱藏時(比如控件所在Activity被pause陆馁,或者失去焦點)是否自動保存當(dāng)前播放狀態(tài)找颓,
*                                 用于再次顯示之后的恢復(fù)到之前的播放狀態(tài)(默認為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ù)對象
*/
void setPlayingMedia(PineMediaPlayerBean pineMediaPlayerBean);

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

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

更多API請參考PineMediaWidget.IPineMediaPlayer接口

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

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

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

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

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

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

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

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

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

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末皱炉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子狮鸭,更是在濱河造成了極大的恐慌合搅,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歧蕉,死亡現(xiàn)場離奇詭異灾部,居然都是意外死亡,警方通過查閱死者的電腦和手機惯退,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門赌髓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人催跪,你說我怎么就攤上這事锁蠕。” “怎么了叠荠?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵匿沛,是天一觀的道長。 經(jīng)常有香客問我榛鼎,道長逃呼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任者娱,我火速辦了婚禮抡笼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘黄鳍。我一直安慰自己推姻,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布框沟。 她就那樣靜靜地躺著藏古,像睡著了一般增炭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拧晕,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天隙姿,我揣著相機與錄音,去河邊找鬼厂捞。 笑死输玷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的靡馁。 我是一名探鬼主播欲鹏,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼臭墨!你這毒婦竟也來了赔嚎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤裙犹,失蹤者是張志新(化名)和其女友劉穎尽狠,沒想到半個月后衔憨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叶圃,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年践图,在試婚紗的時候發(fā)現(xiàn)自己被綠了掺冠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡码党,死狀恐怖德崭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情揖盘,我是刑警寧澤眉厨,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站兽狭,受9級特大地震影響憾股,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箕慧,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一服球、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颠焦,春花似錦斩熊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分冈。三九已至,卻和暖如春霸株,著一層夾襖步出監(jiān)牢的瞬間丈秩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工淳衙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蘑秽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓箫攀,卻偏偏與公主長得像肠牲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子靴跛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容