乐趣区

关于android:03视频播放器Api说明

03. 视频播放器 Api 阐明

目录介绍
  • 01. 最简略的播放
  • 02. 如何切换视频内核
  • 03. 切换视频模式
  • 04. 切换视频清晰度
  • 05. 视频播放监听
  • 06. 列表中播放解决
  • 07. 悬浮窗口播放
  • 08. 其余重要性能 Api
  • 09. 播放多个视频
  • 10.VideoPlayer 相干 Api
  • 11.Controller 相干 Api
  • 12. 边播放边缓存 api
  • 13. 相似抖音视频预加载
  • 14. 视频播放器埋点

00. 视频播放器通用框架

  • 根底封装视频播放器 player,能够在 ExoPlayer、MediaPlayer,声网 RTC 视频播放器内核,原生 MediaPlayer 能够自在切换
  • 对于视图状态切换和前期保护拓展,防止性能和业务呈现耦合。比方须要反对播放器 UI 高度定制,而不是该 lib 库中 UI 代码
  • 针对视频播放,音频播放,播放回放,以及视频直播的性能。应用简略,代码拓展性强,封装性好,次要是和业务彻底解耦,裸露接口监听给开发者解决业务具体逻辑
  • 该播放器整体架构:播放器内核 (自在切换) + 视频播放器 + 边播边缓存 + 高度定制播放器 UI 视图层
  • 我的项目地址:https://github.com/yangchong2…
  • 对于视频播放器整体性能介绍文档:https://juejin.im/post/688345…

01. 最简略的播放

  • 必须须要的四步骤代码如下所示

    // 创立根底视频播放器,个别播放器的性能 BasisVideoController controller = new BasisVideoController(this); // 设置控制器 mVideoPlayer.setVideoController(controller); // 设置视频播放链接地址 mVideoPlayer.setUrl(url); // 开始播放 mVideoPlayer.start(); ```- 开始播放 

    // 播放视频 videoPlayer.start(); `

02. 如何切换视频内核

  • 创立视频播放器

    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); ```- 如何配置视频内核 

    // 播放器配置,留神:此为全局配置,例如上面就是配置 ijk 内核播放器 VideoViewManager.setConfig(VideoPlayerConfig.newBuilder() .setLogEnabled(true)// 调试的时候请关上日志,不便排错 .setPlayerFactory(IjkPlayerFactory.create()) .build()); `– 切换视频内核解决代码

03. 切换视频模式

  • 对于全屏模式相干 api

    // 进入全屏 mVideoPlayer.startFullScreen(); // 退出全屏 mVideoPlayer.stopFullScreen(); ```- 对于小窗口播放相干 api

    // 开启小屏 mVideoPlayer.startTinyScreen(); // 退出小屏 mVideoPlayer.stopTinyScreen(); `

04. 切换视频清晰度

05. 视频播放监听

  • 这个分为两局部:第一局部是播放模式监听,第二局部是播放状态监听,裸露给开发者。这里不倡议应用 0,1,十分不不便扼要之意,采纳注解限定。

    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. 在列表中播放

  • 第一步:初始化视频播放器,创立 VideoPlayer 对象

    mVideoView = new VideoPlayer(context); mVideoView.setOnStateChangeListener(new VideoPlayer.SimpleOnStateChangeListener() {@Override public void onPlayStateChanged(int playState) {// 监听 VideoViewManager 开释,重置状态 if (playState == ConstantKeys.CurrentState.STATE_IDLE) {PlayerUtils.removeViewFormParent(mVideoView); mLastPos = mCurPos; mCurPos = -1; } } }); mController = new BasisVideoController(context); mVideoView.setController(mController); ```- 第二步:设置 RecyclerView 和 Adapter

    mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {@Override public void onItemChildClick(int position) {// 点击 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()) {// 销毁视频 releaseVideoView(); } } }); `– 第三步:播放视频和销毁视频的逻辑代码

    /** * 开始播放 * @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(); // 把列表中预置的 PrepareView 增加到控制器中,留神 isPrivate 此处只能为 true。mController.addControlComponent(viewHolder.mPrepareView, true); PlayerUtils.removeViewFormParent(mVideoView); viewHolder.mPlayerContainer.addView(mVideoView, 0); // 播放之前将 VideoView 增加到 VideoViewManager 以便在别的页面也能操作它 VideoViewManager.instance().add(mVideoView, "list"); mVideoView.start(); mCurPos = position;}     private void releaseVideoView() {

08. 其余重要性能 Api

  • 设置视频播放器背景图,和视频题目。

    // 留神,上面这个 controller 是指 BasisVideoController // 设置视频背景图 ImageView thumb = controller.getThumb(); Glide.with(this).load(R.drawable.image_default).into(controller.getThumb()); // 设置视频题目 controller.setTitle("视频题目"); ```- 判断是否锁屏 

    // 判断是否锁屏 boolean locked = controller.isLocked(); // 设置是否锁屏 controller.setLocked(true); `– 设置播放视频缩放类型。借鉴于网络博客,相似图片缩放。倡议抉择 16:9 类型,最常见

09. 播放多个视频

  • 这个举一个例子,比方同时播放两个视频,当然这种状况在 app 中可能比拟少

    // 必须设置 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);     // 必须设置
    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); ```- 那么要是页面切换到后盾,如何解决多个视频的暂停性能呢?如下所示:

    @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 相干 Api

  • 对于视频播放相干的 api 如下所示

    // 暂停播放 mVideoPlayer.pause(); // 视频缓冲结束,筹备开始播放时回调 mVideoPlayer.onPrepared(); // 从新播放 mVideoPlayer.replay(true); // 持续播放 mVideoPlayer.resume(); // 调整播放进度 mVideoPlayer.seekTo(100); // 循环播放,默认不循环播放 mVideoPlayer.setLooping(true); // 设置播放速度 mVideoPlayer.setSpeed(1.1f); // 设置音量 0.0f-1.0f 之间 mVideoPlayer.setVolume(1,1); // 开始播放 mVideoPlayer.start(); ```- 对于视频切换播放模式相干 api

    // 判断是否处于全屏状态 boolean fullScreen = mVideoPlayer.isFullScreen(); // 是否是小窗口模式 boolean tinyScreen = mVideoPlayer.isTinyScreen(); // 进入全屏 mVideoPlayer.startFullScreen(); // 退出全屏 mVideoPlayer.stopFullScreen(); // 开启小屏 mVideoPlayer.startTinyScreen(); // 退出小屏 mVideoPlayer.stopTinyScreen(); `– 对于其余比方获取速度,音量,设置属性相干 Api

11.Controller 相干 Api

  • Controller 控制器相干的 Api 阐明

12. 边播放边缓存 api

  • 如下所示

13. 相似抖音视频预加载

  • 如下所示,这个是针对 ViewPager

    // 获取 PreloadManager 预加载管理者对象 mPreloadManager = PreloadManager.getInstance(this); // 在播放视频的时候 String playUrl = mPreloadManager.getPlayUrl(url); VideoLogUtils.i("startPlay:" + "position:" + position + "url:" + playUrl); mVideoPlayer.setUrl(playUrl); // 在页面滚动的时候 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); } } }); ```- 如下所示,这个是针对 RecyclerView

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {/* 是否反向滑动 */ 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. 视频播放器埋点

  • 代码如下所示,写一个类,实现 BuriedPointEvent 即可。即可埋点视频的播放次数,播放进度,点击视频广告啥的,不便对立治理
public class BuriedPointEventImpl implements BuriedPointEvent {/** * 进入视频播放 * @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                是否是网络异样 */ @Override public void onError(String url, boolean isNetError) { }
 /** * 点击了视频广告 * @param url                       视频 url */ @Override public void clickAd(String url) { }
 /** * 退出视频播放时候的播放进度百度分 * @param url                       视频 url * @param progress                  视频进度,计算百分比【退出时候进度 / 总进度】*/ @Override public void playerOutProgress(String url, float progress) { }
 /** * 视频切换音频 * @param url                       视频 url */ @Override public void videoToMedia(String url) {}}

15. 播放器示例展现图










退出移动版