android视频播放器api,03.视频播放器Api说明
03.視頻播放器Api說(shuō)明
目錄介紹01.最簡(jiǎn)單的播放
02.如何切換視頻內(nèi)核
03.切換視頻模式
04.切換視頻清晰度
05.視頻播放監(jiān)聽(tīng)
06.列表中播放處理
07.懸浮窗口播放
08.其他重要功能Api
09.播放多個(gè)視頻
10.VideoPlayer相關(guān)Api
11.Controller相關(guān)Api
12.邊播放邊緩存api
13.類(lèi)似抖音視頻預(yù)加載
14.視頻播放器埋點(diǎn)
00.視頻播放器通用框架基礎(chǔ)封裝視頻播放器player,可以在ExoPlayer、MediaPlayer,聲網(wǎng)RTC視頻播放器內(nèi)核,原生MediaPlayer可以自由切換
對(duì)于視圖狀態(tài)切換和后期維護(hù)拓展,避免功能和業(yè)務(wù)出現(xiàn)耦合。比如需要支持播放器UI高度定制,而不是該lib庫(kù)中UI代碼
針對(duì)視頻播放,音頻播放,播放回放,以及視頻直播的功能。使用簡(jiǎn)單,代碼拓展性強(qiáng),封裝性好,主要是和業(yè)務(wù)徹底解耦,暴露接口監(jiān)聽(tīng)給開(kāi)發(fā)者處理業(yè)務(wù)具體邏輯
該播放器整體架構(gòu):播放器內(nèi)核(自由切換) + 視頻播放器 + 邊播邊緩存 + 高度定制播放器UI視圖層
01.最簡(jiǎn)單的播放必須需要的四步驟代碼如下所示//創(chuàng)建基礎(chǔ)視頻播放器,一般播放器的功能 BasisVideoController controller = new BasisVideoController(this); //設(shè)置控制器 mVideoPlayer.setVideoController(controller); //設(shè)置視頻播放鏈接地址 mVideoPlayer.setUrl(url); //開(kāi)始播放 mVideoPlayer.start(); ```- 開(kāi)始播放
//播放視頻 videoPlayer.start(); `
02.如何切換視頻內(nèi)核創(chuàng)建視頻播放器PlayerFactory playerFactory = IjkPlayerFactory.create(); IjkVideoPlayer ijkVideoPlayer = (IjkVideoPlayer) playerFactory.createPlayer(this); PlayerFactory playerFactory = ExoPlayerFactory.create(); ExoMediaPlayer exoMediaPlayer = (ExoMediaPlayer) playerFactory.createPlayer(this); PlayerFactory playerFactory = MediaPlayerFactory.create(); AndroidMediaPlayer androidMediaPlayer = (AndroidMediaPlayer) playerFactory.createPlayer(this); ```- 如何配置視頻內(nèi)核
//播放器配置,注意:此為全局配置,例如下面就是配置ijk內(nèi)核播放器 VideoViewManager.setConfig(VideoPlayerConfig.newBuilder() .setLogEnabled(true)//調(diào)試的時(shí)候請(qǐng)打開(kāi)日志,方便排錯(cuò) .setPlayerFactory(IjkPlayerFactory.create()) .build()); `- 切換視頻內(nèi)核處理代碼
03.切換視頻模式關(guān)于全屏模式相關(guān)api//進(jìn)入全屏 mVideoPlayer.startFullScreen(); //退出全屏 mVideoPlayer.stopFullScreen(); ```- 關(guān)于小窗口播放相關(guān)api
//開(kāi)啟小屏 mVideoPlayer.startTinyScreen(); //退出小屏 mVideoPlayer.stopTinyScreen(); `
04.切換視頻清晰度
05.視頻播放監(jiān)聽(tīng)這個(gè)分為兩部分:第一部分是播放模式監(jiān)聽(tīng),第二部分是播放狀態(tài)監(jiān)聽(tīng),暴露給開(kāi)發(fā)者。這里不建議使用0,1,非常不方便簡(jiǎn)明之意,采用注解限定。mVideoPlayer.setOnStateChangeListener(new OnVideoStateListener() { /** * 播放模式 * 普通模式,小窗口模式,正常模式三種其中一種 * MODE_NORMAL 普通模式 * MODE_FULL_SCREEN 全屏模式 * MODE_TINY_WINDOW 小屏模式 * @param playerState 播放模式 */ @Override public void onPlayerStateChanged(int playerState) { switch (playerState) { case ConstantKeys.PlayMode.MODE_NORMAL: //普通模式 break; case ConstantKeys.PlayMode.MODE_FULL_SCREEN: //全屏模式 break; case ConstantKeys.PlayMode.MODE_TINY_WINDOW: //小屏模式 break; } } /**
06.在列表中播放第一步:初始化視頻播放器,創(chuàng)建VideoPlayer對(duì)象mVideoView = new VideoPlayer(context); mVideoView.setOnStateChangeListener(new VideoPlayer.SimpleOnStateChangeListener() { @Override public void onPlayStateChanged(int playState) { //監(jiān)聽(tīng)VideoViewManager釋放,重置狀態(tài) if (playState == ConstantKeys.CurrentState.STATE_IDLE) { PlayerUtils.removeViewFormParent(mVideoView); mLastPos = mCurPos; mCurPos = -1; } } }); mController = new BasisVideoController(context); mVideoView.setController(mController); ```- 第二步:設(shè)置RecyclerView和Adapter
mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() { @Override public void onItemChildClick(int position) { //點(diǎn)擊item播放視頻 startPlay(position); } }); mRecyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(@NonNull View view) { }@Override
public void onChildViewDetachedFromWindow(@NonNull View view) { FrameLayout playerContainer = view.findViewById(R.id.player_container); View v = playerContainer.getChildAt(0); if (v != null && v == mVideoView && !mVideoView.isFullScreen()) { //銷(xiāo)毀視頻 releaseVideoView(); } } }); `- 第三步:播放視頻和銷(xiāo)毀視頻的邏輯代碼/** * 開(kāi)始播放 * @param position 列表位置 */ protected void startPlay(int position) { if (mCurPos == position) return; if (mCurPos != -1) { releaseVideoView(); } VideoInfoBean videoBean = mVideos.get(position); mVideoView.setUrl(videoBean.getVideoUrl()); View itemView = mLinearLayoutManager.findViewByPosition(position); if (itemView == null) return; VideoRecyclerViewAdapter.VideoHolder viewHolder = (VideoRecyclerViewAdapter.VideoHolder) itemView.getTag(); //把列表中預(yù)置的PrepareView添加到控制器中,注意isPrivate此處只能為true。 mController.addControlComponent(viewHolder.mPrepareView, true); PlayerUtils.removeViewFormParent(mVideoView); viewHolder.mPlayerContainer.addView(mVideoView, 0); //播放之前將VideoView添加到VideoViewManager以便在別的頁(yè)面也能操作它 VideoViewManager.instance().add(mVideoView, "list"); mVideoView.start(); mCurPos = position; } private void releaseVideoView() {
08.其他重要功能Api設(shè)置視頻播放器背景圖,和視頻標(biāo)題。//注意,下面這個(gè)controller是指BasisVideoController //設(shè)置視頻背景圖 ImageView thumb = controller.getThumb(); Glide.with(this).load(R.drawable.image_default).into(controller.getThumb()); //設(shè)置視頻標(biāo)題 controller.setTitle("視頻標(biāo)題"); ```- 判斷是否鎖屏
//判斷是否鎖屏 boolean locked = controller.isLocked(); //設(shè)置是否鎖屏 controller.setLocked(true); `- 設(shè)置播放視頻縮放類(lèi)型。借鑒于網(wǎng)絡(luò)博客,類(lèi)似圖片縮放。建議選擇16:9類(lèi)型,最常見(jiàn)
09.播放多個(gè)視頻這個(gè)舉一個(gè)例子,比如同時(shí)播放兩個(gè)視頻,當(dāng)然這種情況在app中可能比較少//必須設(shè)置 player1.setUrl(VOD_URL_1); VideoPlayerBuilder.Builder builder = VideoPlayerBuilder.newBuilder(); builder.setEnableAudioFocus(false); VideoPlayerBuilder videoPlayerBuilder = new VideoPlayerBuilder(builder); player1.setVideoBuilder(videoPlayerBuilder); BasisVideoController controller1 = new BasisVideoController(this); player1.setController(controller1); mVideoViews.add(player1); //必須設(shè)置
player2.setUrl(VOD_URL_2); VideoPlayerBuilder.Builder builder2 = VideoPlayerBuilder.newBuilder(); builder.setEnableAudioFocus(false); VideoPlayerBuilder videoPlayerBuilder2 = new VideoPlayerBuilder(builder2); player2.setVideoBuilder(videoPlayerBuilder2); BasisVideoController controller2 = new BasisVideoController(this); player2.setController(controller2); mVideoViews.add(player2); ```- 那么要是頁(yè)面切換到后臺(tái),如何處理多個(gè)視頻的暫停功能呢?如下所示:
@Override protected void onPause() { super.onPause(); for (VideoPlayer vv : mVideoViews) { vv.pause(); } } @Override
protected void onResume() { super.onResume(); for (VideoPlayer vv : mVideoViews) { vv.pause(); } } @Override
protected void onDestroy() { super.onDestroy(); for (VideoPlayer vv : mVideoViews) { vv.release(); } } @Override
public void onBackPressed() { for (VideoPlayer vv : mVideoViews) { if (vv.onBackPressed()) return; } super.onBackPressed(); } `
10.VideoPlayer相關(guān)Api關(guān)于視頻播放相關(guān)的api如下所示//暫停播放 mVideoPlayer.pause(); //視頻緩沖完畢,準(zhǔn)備開(kāi)始播放時(shí)回調(diào) mVideoPlayer.onPrepared(); //重新播放 mVideoPlayer.replay(true); //繼續(xù)播放 mVideoPlayer.resume(); //調(diào)整播放進(jìn)度 mVideoPlayer.seekTo(100); //循環(huán)播放, 默認(rèn)不循環(huán)播放 mVideoPlayer.setLooping(true); //設(shè)置播放速度 mVideoPlayer.setSpeed(1.1f); //設(shè)置音量 0.0f-1.0f 之間 mVideoPlayer.setVolume(1,1); //開(kāi)始播放 mVideoPlayer.start(); ```- 關(guān)于視頻切換播放模式相關(guān)api
//判斷是否處于全屏狀態(tài) boolean fullScreen = mVideoPlayer.isFullScreen(); //是否是小窗口模式 boolean tinyScreen = mVideoPlayer.isTinyScreen(); //進(jìn)入全屏 mVideoPlayer.startFullScreen(); //退出全屏 mVideoPlayer.stopFullScreen(); //開(kāi)啟小屏 mVideoPlayer.startTinyScreen(); //退出小屏 mVideoPlayer.stopTinyScreen(); `- 關(guān)于其他比如獲取速度,音量,設(shè)置屬性相關(guān)Api
11.Controller相關(guān)ApiController控制器相關(guān)的Api說(shuō)明
12.邊播放邊緩存api如下所示
13.類(lèi)似抖音視頻預(yù)加載如下所示,這個(gè)是針對(duì)ViewPager//獲取PreloadManager預(yù)加載管理者對(duì)象 mPreloadManager = PreloadManager.getInstance(this); //在播放視頻的時(shí)候 String playUrl = mPreloadManager.getPlayUrl(url); VideoLogUtils.i("startPlay: " + "position: " + position + " url: " + playUrl); mVideoPlayer.setUrl(playUrl); //在頁(yè)面滾動(dòng)的時(shí)候 mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageScrollStateChanged(int state) { super.onPageScrollStateChanged(state); if (state == VerticalViewPager.SCROLL_STATE_IDLE) { mPreloadManager.resumePreload(mCurPos, mIsReverseScroll); } else { mPreloadManager.pausePreload(mCurPos, mIsReverseScroll); } } }); ```- 如下所示,這個(gè)是針對(duì)RecyclerView
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { /* 是否反向滑動(dòng) */ private boolean mIsReverseScroll; @Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (dy>0){ //表示下滑 mIsReverseScroll = false; } else { //表示上滑 mIsReverseScroll = true; } } @Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == VerticalViewPager.SCROLL_STATE_IDLE) { mPreloadManager.resumePreload(mCurPos, mIsReverseScroll); } else { mPreloadManager.pausePreload(mCurPos, mIsReverseScroll); } } }); `
14.視頻播放器埋點(diǎn)代碼如下所示,寫(xiě)一個(gè)類(lèi),實(shí)現(xiàn)BuriedPointEvent即可。即可埋點(diǎn)視頻的播放次數(shù),播放進(jìn)度,點(diǎn)擊視頻廣告啥的,方便統(tǒng)一管理public class BuriedPointEventImpl implements BuriedPointEvent {
/** * 進(jìn)入視頻播放 * @param url 視頻url */ @Override public void playerIn(String url) {
} /**
* 退出視頻播放 * @param url 視頻url */ @Override public void playerDestroy(String url) {
}
/** * 視頻播放完成 * @param url 視頻url */ @Override public void playerCompletion(String url) {
}
/** * 視頻播放異常 * @param url 視頻url * @param isNetError 是否是網(wǎng)絡(luò)異常 */ @Override public void onError(String url, boolean isNetError) {
}
/** * 點(diǎn)擊了視頻廣告 * @param url 視頻url */ @Override public void clickAd(String url) {
}
/** * 退出視頻播放時(shí)候的播放進(jìn)度百度分 * @param url 視頻url * @param progress 視頻進(jìn)度,計(jì)算百分比【退出時(shí)候進(jìn)度 / 總進(jìn)度】 */ @Override public void playerOutProgress(String url, float progress) {
}
/** * 視頻切換音頻 * @param url 視頻url */ @Override public void videoToMedia(String url) {
}}
15.播放器示例展示圖
總結(jié)
以上是生活随笔為你收集整理的android视频播放器api,03.视频播放器Api说明的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 获取页面可见区域,屏幕区域的尺寸
- 下一篇: 2007最受欢迎的十大Ajax技术文章