Quellcode durchsuchen

完善视频播放器

杨充 vor 5 Jahren
Ursprung
Commit
928ac5a925

+ 19 - 2
VideoPlayer/src/main/java/org/yczbj/ycvideoplayerlib/controller/BaseVideoController.java

@@ -214,6 +214,9 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
         mControlComponents.remove(component);
     }
 
+    /**
+     * 移除所有的组件
+     */
     public void removeAllControlComponent() {
         for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
             removeView(next.getKey().getView());
@@ -253,6 +256,8 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
     public void setDismissTimeout(int timeout) {
         if (timeout > 0) {
             mDefaultTimeout = timeout;
+        } else {
+            mDefaultTimeout = 5000;
         }
     }
 
@@ -300,7 +305,9 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
      */
     @Override
     public void stopFadeOut() {
-        removeCallbacks(mFadeOut);
+        if (mFadeOut!=null){
+            removeCallbacks(mFadeOut);
+        }
     }
 
     /**
@@ -313,12 +320,20 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
         }
     };
 
+    /**
+     * 设置是否锁屏
+     * @param locked                        是否锁定
+     */
     @Override
     public void setLocked(boolean locked) {
         mIsLocked = locked;
         handleLockStateChanged(locked);
     }
 
+    /**
+     * 判断是否锁屏
+     * @return                              返回是否锁屏
+     */
     @Override
     public boolean isLocked() {
         return mIsLocked;
@@ -341,7 +356,9 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
      */
     @Override
     public void stopProgress() {
-        if (!mIsStartProgress) return;
+        if (!mIsStartProgress) {
+            return;
+        }
         removeCallbacks(mShowProgress);
         mIsStartProgress = false;
     }

+ 21 - 9
VideoPlayer/src/main/java/org/yczbj/ycvideoplayerlib/player/VideoPlayer.java

@@ -683,6 +683,10 @@ public class VideoPlayer<P extends AbstractVideoPlayer> extends FrameLayout
         }
     }
 
+    /**
+     * 获取倍速速度
+     * @return                              速度
+     */
     @Override
     public float getSpeed() {
         if (isInPlaybackState()) {
@@ -826,9 +830,13 @@ public class VideoPlayer<P extends AbstractVideoPlayer> extends FrameLayout
      * 开启小屏
      */
     public void startTinyScreen() {
-        if (mIsTinyScreen) return;
+        if (mIsTinyScreen) {
+            return;
+        }
         ViewGroup contentView = VideoPlayerHelper.instance().getContentView(mContext,mVideoController);
-        if (contentView == null) return;
+        if (contentView == null) {
+            return;
+        }
         this.removeView(mPlayerContainer);
         int width = mTinyScreenSize[0];
         if (width <= 0) {
@@ -849,20 +857,24 @@ public class VideoPlayer<P extends AbstractVideoPlayer> extends FrameLayout
      * 退出小屏
      */
     public void stopTinyScreen() {
-        if (!mIsTinyScreen) return;
-
+        if (!mIsTinyScreen) {
+            return;
+        }
         ViewGroup contentView = VideoPlayerHelper.instance().getContentView(mContext,mVideoController);
-        if (contentView == null) return;
+        if (contentView == null) {
+            return;
+        }
         contentView.removeView(mPlayerContainer);
-        LayoutParams params = new LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT);
+        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
         this.addView(mPlayerContainer, params);
-
         mIsTinyScreen = false;
         setPlayerState(ConstantKeys.PlayMode.MODE_NORMAL);
     }
 
+    /**
+     * 是否是小窗口模式
+     * @return                              是否是小窗口模式
+     */
     public boolean isTinyScreen() {
         return mIsTinyScreen;
     }

+ 11 - 9
VideoPlayer/src/main/java/org/yczbj/ycvideoplayerlib/ui/view/BasisVideoController.java

@@ -52,6 +52,7 @@ public class BasisVideoController extends GestureVideoController implements View
     private ImageView mLockButton;
     private ProgressBar mLoadingProgress;
     private ImageView thumb;
+    private CustomTitleView titleView;
 
     public BasisVideoController(@NonNull Context context) {
         this(context, null);
@@ -98,11 +99,6 @@ public class BasisVideoController extends GestureVideoController implements View
         //滑动调节亮度,音量,进度,默认开启
         setGestureEnabled(true);
 
-        //添加与加载视图界面view,准备播放界面
-        CustomPrepareView prepareView = new CustomPrepareView(mContext);
-        thumb = prepareView.getThumb();
-        prepareView.setClickStart();
-        this.addControlComponent(prepareView);
         addDefaultControlComponent("",false);
     }
 
@@ -132,7 +128,7 @@ public class BasisVideoController extends GestureVideoController implements View
         this.addControlComponent(prepareView);
 
         //添加标题栏
-        CustomTitleView titleView = new CustomTitleView(mContext);
+        titleView = new CustomTitleView(mContext);
         titleView.setTitle(title);
         titleView.setVisibility(VISIBLE);
         this.addControlComponent(titleView);
@@ -271,12 +267,18 @@ public class BasisVideoController extends GestureVideoController implements View
         return super.onBackPressed();
     }
 
+    @Override
+    public void destroy() {
+
+    }
+
     public ImageView getThumb() {
         return thumb;
     }
 
-    @Override
-    public void destroy() {
-
+    public void setTitle(String title) {
+        if (titleView!=null){
+            titleView.setTitle(title);
+        }
     }
 }

+ 2 - 3
app/src/main/java/org/yczbj/ycvideoplayer/newPlayer/activity/MultipleActivity.java

@@ -38,19 +38,18 @@ public class MultipleActivity extends AppCompatActivity {
     }
 
     private void initVideoPlayer() {
-        player1.setUrl(VOD_URL_1);
         //必须设置
+        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);
         //必须设置
+        player2.setUrl(VOD_URL_2);
         VideoPlayerBuilder.Builder builder2 = VideoPlayerBuilder.newBuilder();
         builder.setEnableAudioFocus(false);
         VideoPlayerBuilder videoPlayerBuilder2 = new VideoPlayerBuilder(builder2);

+ 191 - 1
app/src/main/java/org/yczbj/ycvideoplayer/newPlayer/activity/NormalActivity.java

@@ -1,9 +1,11 @@
 package org.yczbj.ycvideoplayer.newPlayer.activity;
 
+import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;
+import android.widget.ImageView;
 
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
@@ -13,9 +15,11 @@ import com.bumptech.glide.Glide;
 import org.yczbj.ycvideoplayer.ConstantVideo;
 import org.yczbj.ycvideoplayer.R;
 import org.yczbj.ycvideoplayerlib.config.ConstantKeys;
+import org.yczbj.ycvideoplayerlib.player.OnVideoStateListener;
 import org.yczbj.ycvideoplayerlib.player.VideoPlayer;
 import org.yczbj.ycvideoplayerlib.player.VideoPlayerBuilder;
 import org.yczbj.ycvideoplayerlib.ui.view.BasisVideoController;
+import org.yczbj.ycvideoplayerlib.ui.view.CustomErrorView;
 
 public class NormalActivity extends AppCompatActivity implements View.OnClickListener {
 
@@ -25,6 +29,7 @@ public class NormalActivity extends AppCompatActivity implements View.OnClickLis
     private Button mBtnScale43;
     private Button mBtnCrop;
     private Button mBtnGif;
+    private BasisVideoController controller;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -39,6 +44,7 @@ public class NormalActivity extends AppCompatActivity implements View.OnClickLis
     protected void onResume() {
         super.onResume();
         if (mVideoPlayer != null) {
+            //从后台切换到前台,当视频暂停时或者缓冲暂停时,调用该方法重新开启视频播放
             mVideoPlayer.resume();
         }
     }
@@ -48,6 +54,7 @@ public class NormalActivity extends AppCompatActivity implements View.OnClickLis
     protected void onPause() {
         super.onPause();
         if (mVideoPlayer != null) {
+            //从前台切到后台,当视频正在播放或者正在缓冲时,调用该方法暂停视频
             mVideoPlayer.pause();
         }
     }
@@ -56,12 +63,14 @@ public class NormalActivity extends AppCompatActivity implements View.OnClickLis
     protected void onDestroy() {
         super.onDestroy();
         if (mVideoPlayer != null) {
+            //销毁页面,释放,内部的播放器被释放掉,同时如果在全屏、小窗口模式下都会退出
             mVideoPlayer.release();
         }
     }
 
     @Override
     public void onBackPressed() {
+        //处理返回键逻辑;如果是全屏,则退出全屏;如果是小窗口,则退出小窗口
         if (mVideoPlayer == null || !mVideoPlayer.onBackPressed()) {
             super.onBackPressed();
         }
@@ -79,13 +88,19 @@ public class NormalActivity extends AppCompatActivity implements View.OnClickLis
     private void initVideoPlayer() {
         String url = ConstantVideo.VideoPlayerList[0];
         //创建基础视频播放器,一般播放器的功能
-        BasisVideoController controller = new BasisVideoController(this);
+        controller = new BasisVideoController(this);
         //设置控制器
         mVideoPlayer.setController(controller);
         //设置视频播放链接地址
         mVideoPlayer.setUrl(url);
         //开始播放
         mVideoPlayer.start();
+        mVideoPlayer.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                mVideoPlayer.start();
+            }
+        },300);
         //设置视频背景图
         Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
     }
@@ -126,6 +141,181 @@ public class NormalActivity extends AppCompatActivity implements View.OnClickLis
         //是否开启AudioFocus监听, 默认开启
         builder.setEnableAudioFocus(false);
         mVideoPlayer.setVideoBuilder(videoPlayerBuilder);
+        //截图
+        Bitmap bitmap = mVideoPlayer.doScreenShot();
+        //移除所有播放状态监听
+        mVideoPlayer.clearOnStateChangeListeners();
+        //获取当前缓冲百分比
+        int bufferedPercentage = mVideoPlayer.getBufferedPercentage();
+        //获取当前播放器的状态
+        int currentPlayerState = mVideoPlayer.getCurrentPlayerState();
+        //获取当前的播放状态
+        int currentPlayState = mVideoPlayer.getCurrentPlayState();
+        //获取当前播放的位置
+        long currentPosition = mVideoPlayer.getCurrentPosition();
+        //获取视频总时长
+        long duration = mVideoPlayer.getDuration();
+        //获取倍速速度
+        float speed = mVideoPlayer.getSpeed();
+        //获取缓冲速度
+        long tcpSpeed = mVideoPlayer.getTcpSpeed();
+        //获取视频宽高
+        int[] videoSize = mVideoPlayer.getVideoSize();
+        //是否处于静音状态
+        boolean mute = mVideoPlayer.isMute();
+        //判断是否处于全屏状态
+        boolean fullScreen = mVideoPlayer.isFullScreen();
+        //是否是小窗口模式
+        boolean tinyScreen = mVideoPlayer.isTinyScreen();
+
+        //是否处于播放状态
+        boolean playing = mVideoPlayer.isPlaying();
+        //暂停播放
+        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();
+
+
+        //进入全屏
+        mVideoPlayer.startFullScreen();
+        //退出全屏
+        mVideoPlayer.stopFullScreen();
+        //开启小屏
+        mVideoPlayer.startTinyScreen();
+        //退出小屏
+        mVideoPlayer.stopTinyScreen();
+
+        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;
+                }
+            }
+
+            /**
+             * 播放状态
+             * -1               播放错误
+             * 0                播放未开始
+             * 1                播放准备中
+             * 2                播放准备就绪
+             * 3                正在播放
+             * 4                暂停播放
+             * 5                正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)
+             * 6                暂停缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,此时暂停播放器,继续缓冲,缓冲区数据足够后恢复暂停
+             * 7                播放完成
+             * 8                开始播放中止
+             * @param playState                         播放状态,主要是指播放器的各种状态
+             */
+            @Override
+            public void onPlayStateChanged(int playState) {
+                switch (playState) {
+                    case ConstantKeys.CurrentState.STATE_IDLE:
+                        //播放未开始,初始化
+                        break;
+                    case ConstantKeys.CurrentState.STATE_START_ABORT:
+                        //开始播放中止
+                        break;
+                    case ConstantKeys.CurrentState.STATE_PREPARING:
+                        //播放准备中
+                        break;
+                    case ConstantKeys.CurrentState.STATE_PREPARED:
+                        //播放准备就绪
+                        break;
+                    case ConstantKeys.CurrentState.STATE_ERROR:
+                        //播放错误
+                        break;
+                    case ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING:
+                        //正在缓冲
+                        break;
+                    case ConstantKeys.CurrentState.STATE_PLAYING:
+                        //正在播放
+                        break;
+                    case ConstantKeys.CurrentState.STATE_PAUSED:
+                        //暂停播放
+                        break;
+                    case ConstantKeys.CurrentState.STATE_BUFFERING_PAUSED:
+                        //暂停缓冲
+                        break;
+                    case ConstantKeys.CurrentState.STATE_COMPLETED:
+                        //播放完成
+                        break;
+                }
+            }
+        });
+
+        //设置视频背景图
+        ImageView thumb = controller.getThumb();
+        Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
+        //设置视频标题
+        controller.setTitle("视频标题");
+        //添加自定义视图。每添加一个视图,都是方式层级树的最上层
+        CustomErrorView customErrorView = new CustomErrorView(this);
+        controller.addControlComponent(customErrorView);
+        //移除控制组件
+        controller.removeControlComponent(customErrorView);
+        //移除所有的组件
+        controller.removeAllControlComponent();
+        //隐藏播放视图
+        controller.hide();
+        //显示播放视图
+        controller.show();
+        //是否开启根据屏幕方向进入/退出全屏
+        controller.setEnableOrientation(true);
+        //显示移动网络播放提示
+        controller.showNetWarning();
+        //刘海的高度
+        int cutoutHeight = controller.getCutoutHeight();
+        //是否有刘海屏
+        boolean b = controller.hasCutout();
+        //设置是否适配刘海屏
+        controller.setAdaptCutout(true);
+        //停止刷新进度
+        controller.stopProgress();
+        //开始刷新进度,注意:需在STATE_PLAYING时调用才会开始刷新进度
+        controller.startProgress();
+        //判断是否锁屏
+        boolean locked = controller.isLocked();
+        //设置是否锁屏
+        controller.setLocked(true);
+        //取消计时
+        controller.stopFadeOut();
+        //开始计时
+        controller.startFadeOut();
+        //设置播放视图自动隐藏超时
+        controller.setDismissTimeout(8);
+        //销毁
+        controller.destroy();
     }
 
 }

+ 9 - 0
app/src/main/java/org/yczbj/ycvideoplayer/newPlayer/activity/TypeActivity.java

@@ -22,10 +22,16 @@ import org.yczbj.ycvideoplayer.newPlayer.surface.TestSurfaceActivity;
 import org.yczbj.ycvideoplayer.newPlayer.tiny.TestFullActivity;
 import org.yczbj.ycvideoplayer.newPlayer.tiny.TinyScreenActivity;
 import org.yczbj.ycvideoplayerlib.config.ConstantKeys;
+
+import com.yc.kernel.impl.exo.ExoMediaPlayer;
 import com.yc.kernel.impl.exo.ExoPlayerFactory;
 import com.yc.kernel.impl.ijk.IjkPlayerFactory;
+import com.yc.kernel.impl.ijk.IjkVideoPlayer;
+import com.yc.kernel.impl.media.AndroidMediaPlayer;
 import com.yc.kernel.impl.media.MediaPlayerFactory;
 import com.yc.kernel.factory.PlayerFactory;
+import com.yc.kernel.inter.AbstractVideoPlayer;
+
 import org.yczbj.ycvideoplayerlib.player.VideoPlayerConfig;
 import org.yczbj.ycvideoplayerlib.player.VideoViewManager;
 import org.yczbj.ycvideoplayerlib.tool.BaseToast;
@@ -200,14 +206,17 @@ public class TypeActivity extends AppCompatActivity implements View.OnClickListe
             switch (type) {
                 case ConstantKeys.VideoPlayerType.TYPE_IJK:
                     playerFactory = IjkPlayerFactory.create();
+                    IjkVideoPlayer ijkVideoPlayer = (IjkVideoPlayer) playerFactory.createPlayer(this);
                     mTvTitle.setText("视频内核:" + " (IjkPlayer)");
                     break;
                 case ConstantKeys.VideoPlayerType.TYPE_EXO:
                     playerFactory = ExoPlayerFactory.create();
+                    ExoMediaPlayer exoMediaPlayer = (ExoMediaPlayer) playerFactory.createPlayer(this);
                     mTvTitle.setText("视频内核:" + " (ExoPlayer)");
                     break;
                 case ConstantKeys.VideoPlayerType.TYPE_NATIVE:
                     playerFactory = MediaPlayerFactory.create();
+                    AndroidMediaPlayer androidMediaPlayer = (AndroidMediaPlayer) playerFactory.createPlayer(this);
                     mTvTitle.setText("视频内核:" + " (MediaPlayer)");
                     break;
                 case ConstantKeys.VideoPlayerType.TYPE_RTC:

+ 7 - 1
app/src/main/java/org/yczbj/ycvideoplayer/newPlayer/ad/AdControlView.java

@@ -16,12 +16,14 @@ import androidx.annotation.Nullable;
 import org.yczbj.ycvideoplayer.R;
 import org.yczbj.ycvideoplayerlib.config.ConstantKeys;
 import org.yczbj.ycvideoplayerlib.controller.ControlWrapper;
+import org.yczbj.ycvideoplayerlib.ui.view.CustomTitleView;
 import org.yczbj.ycvideoplayerlib.ui.view.InterControlView;
 import org.yczbj.ycvideoplayerlib.tool.PlayerUtils;
 
 
 public class AdControlView extends FrameLayout implements InterControlView, View.OnClickListener {
 
+    private Context mContext;
     protected TextView mAdTime, mAdDetail;
     protected ImageView mBack, mVolume, mFullScreen, mPlayButton;
     protected AdControlListener mListener;
@@ -30,17 +32,21 @@ public class AdControlView extends FrameLayout implements InterControlView, View
 
     public AdControlView(@NonNull Context context) {
         super(context);
+        init(context);
     }
 
     public AdControlView(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
+        init(context);
     }
 
     public AdControlView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
+        init(context);
     }
 
-    {
+    private void init(Context context){
+        this.mContext = context;
         LayoutInflater.from(getContext()).inflate(R.layout.layout_ad_control_view, this, true);
         mAdTime = findViewById(R.id.ad_time);
         mAdDetail = findViewById(R.id.ad_detail);

+ 1 - 0
app/src/main/java/org/yczbj/ycvideoplayer/newPlayer/tiny/TestFullActivity.java

@@ -11,6 +11,7 @@ import org.yczbj.ycvideoplayer.BaseActivity;
 import org.yczbj.ycvideoplayer.ConstantVideo;
 import org.yczbj.ycvideoplayer.R;
 import org.yczbj.ycvideoplayerlib.config.ConstantKeys;
+import org.yczbj.ycvideoplayerlib.player.OnVideoStateListener;
 import org.yczbj.ycvideoplayerlib.player.VideoPlayer;
 import org.yczbj.ycvideoplayerlib.ui.view.BasisVideoController;
 

+ 128 - 37
read/01.视频播放器介绍文档.md

@@ -7,7 +7,7 @@
 - 05.播放器详细Api文档
 - 06.播放器封装思路
 - 07.播放器示例展示图
-- 08.播放器悬浮窗口介绍
+- 08.添加自定义视图
 - 09.视频优化处理
 - 10.播放器问题记录说明
 - 11.性能优化和库大小
@@ -88,6 +88,8 @@
     - C.1.4 锁定屏幕功能,这个参考大部分播放器,只有在全屏模式下才会有
 
 
+
+
 ### 03.视频播放器结构说明
 - 视频常见的布局视图
     - 视频底图(用于显示初始化视频时的封面图),视频状态视图【加载loading,播放异常,加载视频失败,播放完成等】
@@ -127,7 +129,7 @@
     
     ```
 
-#### 4.2 添加布局
+#### 4.2 在xml中添加布局
 - 注意,在实际开发中,由于Android手机碎片化比较严重,分辨率太多了,建议灵活设置布局的宽高比为4:3或者16:9或者你认为合适的,可以用代码设置。
 - 如果宽高比变形,则会有黑边
     ```
@@ -150,62 +152,150 @@
     mVideoPlayer.start();
     ```
 
+#### 4.4 注意问题
+- 如果是全屏播放,则需要在清单文件中设置当前activity的属性值
+    - android:configChanges 保证了在全屏的时候横竖屏切换不会执行Activity的相关生命周期,打断视频的播放
+    - android:screenOrientation 固定了屏幕的初始方向
+    - 这两个变量控制全屏后和退出全屏的屏幕方向
+        ```
+            <activity android:name=".VideoActivity"
+                android:configChanges="orientation|keyboardHidden|screenSize"
+                android:screenOrientation="portrait"/>
+        ```
+- 如何一进入页面就开始播放视频,稍微延时一下即可
+    - 代码如下所示,注意避免直接start(),因为有可能视频还没有初始化完成……
+        ```
+        mVideoPlayer.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                mVideoPlayer.start();
+            }
+        },300);
+        ```
+
+
+
+### 05.播放器详细Api文档
+
+
+### 06.播放器封装思路
+
+
+### 07.播放器示例展示图
+
+
+### 08.添加自定义视图
+- 比如,现在有个业务需求,需要在视频播放器刚开始添加一个广告视图,等待广告倒计时120秒后,直接进入播放视频逻辑。相信这个业务场景很常见,大家都碰到过,使用该播放器就特别简单,代码如下所示:
+- 首先创建一个自定义view,需要实现InterControlView接口,重写该接口中所有抽象方法,这里省略了很多代码,具体看demo。
+    ``` java
+    public class AdControlView extends FrameLayout implements InterControlView, View.OnClickListener {
+    
+        private ControlWrapper mControlWrapper;
+        public AdControlView(@NonNull Context context) {
+            super(context);
+            init(context);
+        }
+    
+        private void init(Context context){
+            LayoutInflater.from(getContext()).inflate(R.layout.layout_ad_control_view, this, true);
+        }
+       
+        @Override
+        public void onPlayStateChanged(int playState) {
+            switch (playState) {
+                case ConstantKeys.CurrentState.STATE_PLAYING:
+                    mControlWrapper.startProgress();
+                    mPlayButton.setSelected(true);
+                    break;
+                case ConstantKeys.CurrentState.STATE_PAUSED:
+                    mPlayButton.setSelected(false);
+                    break;
+            }
+        }
+    
+        @Override
+        public void onPlayerStateChanged(int playerState) {
+            switch (playerState) {
+                case ConstantKeys.PlayMode.MODE_NORMAL:
+                    mBack.setVisibility(GONE);
+                    mFullScreen.setSelected(false);
+                    break;
+                case ConstantKeys.PlayMode.MODE_FULL_SCREEN:
+                    mBack.setVisibility(VISIBLE);
+                    mFullScreen.setSelected(true);
+                    break;
+            }
+            //暂未实现全面屏适配逻辑,需要你自己补全
+        }
+    }
+    ```
+- 然后该怎么使用这个自定义view呢?很简单,在之前基础上,通过控制器对象add进来即可,代码如下所示
+    ``` java
+    controller = new BasisVideoController(this);
+    AdControlView adControlView = new AdControlView(this);
+    adControlView.setListener(new AdControlView.AdControlListener() {
+        @Override
+        public void onAdClick() {
+            BaseToast.showRoundRectToast( "广告点击跳转");
+        }
+    
+        @Override
+        public void onSkipAd() {
+            playVideo();
+        }
+    });
+    controller.addControlComponent(adControlView);
+    //设置控制器
+    mVideoPlayer.setController(controller);
+    mVideoPlayer.setUrl(proxyUrl);
+    mVideoPlayer.start();
+    ```
 
-#### 2.4 优化代码
+
+### 09.视频优化处理
 - **如果是在Activity中的话,建议设置下面这段代码**
     ```
     @Override
-    protected void onStop() {
-        super.onStop();
-        //从前台切到后台,当视频正在播放或者正在缓冲时,调用该方法暂停视频
-        VideoPlayerManager.instance().suspendVideoPlayer();
+    protected void onResume() {
+        super.onResume();
+        if (mVideoPlayer != null) {
+            //从后台切换到前台,当视频暂停时或者缓冲暂停时,调用该方法重新开启视频播放
+            mVideoPlayer.resume();
+        }
+    }
+
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (mVideoPlayer != null) {
+            //从前台切到后台,当视频正在播放或者正在缓冲时,调用该方法暂停视频
+            mVideoPlayer.pause();
+        }
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        //销毁页面,释放,内部的播放器被释放掉,同时如果在全屏、小窗口模式下都会退出
-        VideoPlayerManager.instance().releaseVideoPlayer();
+        if (mVideoPlayer != null) {
+            //销毁页面,释放,内部的播放器被释放掉,同时如果在全屏、小窗口模式下都会退出
+            mVideoPlayer.release();
+        }
     }
 
     @Override
     public void onBackPressed() {
         //处理返回键逻辑;如果是全屏,则退出全屏;如果是小窗口,则退出小窗口
-        if (VideoPlayerManager.instance().onBackPressed()){
-            return;
-        }else {
-            //销毁页面
-            VideoPlayerManager.instance().releaseVideoPlayer();
+        if (mVideoPlayer == null || !mVideoPlayer.onBackPressed()) {
+            super.onBackPressed();
         }
-        super.onBackPressed();
-    }
-
-    @Override
-    protected void onRestart() {
-        super.onRestart();
-        //从后台切换到前台,当视频暂停时或者缓冲暂停时,调用该方法重新开启视频播放
-        VideoPlayerManager.instance().resumeVideoPlayer();
     }
     ```
 
 
-### 05.播放器详细Api文档
-
-
-### 06.播放器封装思路
-
-
-### 07.播放器示例展示图
-
-
-### 08.播放器悬浮窗口介绍
-
-
-### 09.视频优化处理
-
-
 ### 10.播放器问题记录说明
 
+
 ### 11.性能优化和库大小
 
 
@@ -218,6 +308,7 @@
     - 比如,视频player,日志过滤则是:bbb
 
 
+
 ### 14.该库异常code说明
 
 

+ 372 - 55
read/03.视频播放器Api说明.md

@@ -1,89 +1,406 @@
 # 基础方法说明
 #### 目录介绍
 - 01.最简单的播放
-- 02.竖屏全屏播放
-- 03.横屏全屏播放
-- 04.小窗口播放
-- 05.全屏播放切换视频清晰度
-- 06.在列表中播放
-- 07.在activity播放视频处理home键逻辑
-- 08.在fragment中播放
-- 09.1 显示正常视频top[分享,下载,更多按钮控件]
-- 09.2 显示横屏视频top[tv投影,切换音频控件]
-- 10.全局悬浮播放视频
-- 11.常见api说明
-
+- 02.如何切换视频内核
+- 03.切换视频模式
+- 04.切换视频清晰度
+- 05.视频播放监听
+- 06.列表中播放处理
+- 07.悬浮窗口播放
+- 08.其他重要功能Api
+- 09.播放多个视频
+- 10.VideoPlayer相关Api
+- 11.Controller相关Api
 
 
 
 ### 01.最简单的播放
 - 必须需要的四步骤代码如下所示
-    ```
-    //设置播放类型
-    videoPlayer.setPlayerType(ConstantKeys.IjkPlayerType.TYPE_IJK);
-    //设置视频地址和请求头部
-    videoPlayer.setUp(urls, null);
-    //创建视频控制器
-    controller = new VideoPlayerController(this);
-    //设置视频控制器
-    videoPlayer.setController(controller);
+    ``` java
+    //创建基础视频播放器,一般播放器的功能
+    BasisVideoController controller = new BasisVideoController(this);
+    //设置控制器
+    mVideoPlayer.setVideoController(controller);
+    //设置视频播放链接地址
+    mVideoPlayer.setUrl(url);
+    //开始播放
+    mVideoPlayer.start();
     ```
 - 开始播放
-    ```
+    ``` java
     //播放视频
     videoPlayer.start();
     ```
-- 是否设置从上一次的位置继续播放,这个参数你可以自己设置,默认是true
-    ```
-    videoPlayer.continueFromLastPosition(true);
-    ```
 
 
-### 02.竖屏全屏播放
-- 如下所示
-    ```
-    //进入竖屏的全屏模式
-    videoPlayer.enterVerticalScreenScreen();
+### 02.如何切换视频内核
+- 创建视频播放器
+    ``` java
+    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);
+    ```
+- 如何配置视频内核
+    ``` java
+    //播放器配置,注意:此为全局配置,例如下面就是配置ijk内核播放器
+    VideoViewManager.setConfig(VideoPlayerConfig.newBuilder()
+            .setLogEnabled(true)//调试的时候请打开日志,方便排错
+            .setPlayerFactory(IjkPlayerFactory.create())
+            .build());
+    ```
+- 切换视频内核处理代码
+    ``` java
+    @SuppressLint("SetTextI18n")
+    private void setChangeVideoType(@ConstantKeys.PlayerType int type){
+        //切换播放核心,不推荐这么做,我这么写只是为了方便测试
+        VideoPlayerConfig config = VideoViewManager.getConfig();
+        try {
+            Field mPlayerFactoryField = config.getClass().getDeclaredField("mPlayerFactory");
+            mPlayerFactoryField.setAccessible(true);
+            PlayerFactory playerFactory = null;
+            switch (type) {
+                case ConstantKeys.VideoPlayerType.TYPE_IJK:
+                    playerFactory = IjkPlayerFactory.create();
+                    mTvTitle.setText("视频内核:" + " (IjkPlayer)");
+                    break;
+                case ConstantKeys.VideoPlayerType.TYPE_EXO:
+                    playerFactory = ExoPlayerFactory.create();
+                    mTvTitle.setText("视频内核:" + " (ExoPlayer)");
+                    break;
+                case ConstantKeys.VideoPlayerType.TYPE_NATIVE:
+                    playerFactory = MediaPlayerFactory.create();
+                    mTvTitle.setText("视频内核:" + " (MediaPlayer)");
+                    break;
+                case ConstantKeys.VideoPlayerType.TYPE_RTC:
+                    break;
+            }
+            mPlayerFactoryField.set(config, playerFactory);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
     ```
 
-### 03.横屏全屏播放
-- 如下所示
+
+### 03.切换视频模式
+- 关于全屏模式相关api
+    ``` java
+    //进入全屏
+    mVideoPlayer.startFullScreen();
+    //退出全屏
+    mVideoPlayer.stopFullScreen();
     ```
-    //进入全屏模式
-    videoPlayer.enterFullScreen();
+- 关于小窗口播放相关api
+    ``` java
+    //开启小屏
+    mVideoPlayer.startTinyScreen();
+    //退出小屏
+    mVideoPlayer.stopTinyScreen();
     ```
 
 
-### 04.小窗口播放
-- 如下所示
+### 04.切换视频清晰度
+
+
+
+### 05.视频播放监听
+- 这个分为两部分:第一部分是播放模式监听,第二部分是播放状态监听,暴露给开发者。这里不建议使用0,1,非常不方便简明之意,采用注解限定。
     ```
-    //进入小窗口播放
-    videoPlayer.enterTinyWindow();
+    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;
+            }
+        }
+    
+        /**
+         * 播放状态
+         * -1               播放错误
+         * 0                播放未开始
+         * 1                播放准备中
+         * 2                播放准备就绪
+         * 3                正在播放
+         * 4                暂停播放
+         * 5                正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)
+         * 6                暂停缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,此时暂停播放器,继续缓冲,缓冲区数据足够后恢复暂停
+         * 7                播放完成
+         * 8                开始播放中止
+         * @param playState                         播放状态,主要是指播放器的各种状态
+         */
+        @Override
+        public void onPlayStateChanged(int playState) {
+            switch (playState) {
+                case ConstantKeys.CurrentState.STATE_IDLE:
+                    //播放未开始,初始化
+                    break;
+                case ConstantKeys.CurrentState.STATE_START_ABORT:
+                    //开始播放中止
+                    break;
+                case ConstantKeys.CurrentState.STATE_PREPARING:
+                    //播放准备中
+                    break;
+                case ConstantKeys.CurrentState.STATE_PREPARED:
+                    //播放准备就绪
+                    break;
+                case ConstantKeys.CurrentState.STATE_ERROR:
+                    //播放错误
+                    break;
+                case ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING:
+                    //正在缓冲
+                    break;
+                case ConstantKeys.CurrentState.STATE_PLAYING:
+                    //正在播放
+                    break;
+                case ConstantKeys.CurrentState.STATE_PAUSED:
+                    //暂停播放
+                    break;
+                case ConstantKeys.CurrentState.STATE_BUFFERING_PAUSED:
+                    //暂停缓冲
+                    break;
+                case ConstantKeys.CurrentState.STATE_COMPLETED:
+                    //播放完成
+                    break;
+            }
+        }
+    });
     ```
 
 
-### 05.全屏播放切换视频清晰度
-- 代码如下所示
-    ```
-    mVideoPlayer.setPlayerType(ConstantKeys.IjkPlayerType.TYPE_IJK);
-    VideoPlayerController controller = new VideoPlayerController(this);
-    controller.setClarity(getClarites(), 0);
-    mVideoPlayer.setController(controller);
 
 
-    //设置清晰度的话,需要传递不同的视频链接
-    public List<VideoClarity> getClarites() {
-        List<VideoClarity> clarities = new ArrayList<>();
-        clarities.add(new VideoClarity("标清", "270P", "http://play.g3proxy.lecloud.com/vod/v2/MjUxLzE2LzgvbGV0di11dHMvMTQvdmVyXzAwXzIyLTExMDc2NDEzODctYXZjLTE5OTgxOS1hYWMtNDgwMDAtNTI2MTEwLTE3MDg3NjEzLWY1OGY2YzM1NjkwZTA2ZGFmYjg2MTVlYzc5MjEyZjU4LTE0OTg1NTc2ODY4MjMubXA0?b=259&mmsid=65565355&tm=1499247143&key=f0eadb4f30c404d49ff8ebad673d3742&platid=3&splatid=345&playid=0&tss=no&vtype=21&cvid=2026135183914&payff=0&pip=08cc52f8b09acd3eff8bf31688ddeced&format=0&sign=mb&dname=mobile&expect=1&tag=mobile&xformat=super"));
-        clarities.add(new VideoClarity("高清", "480P", "http://play.g3proxy.lecloud.com/vod/v2/MjQ5LzM3LzIwL2xldHYtdXRzLzE0L3Zlcl8wMF8yMi0xMTA3NjQxMzkwLWF2Yy00MTk4MTAtYWFjLTQ4MDAwLTUyNjExMC0zMTU1NTY1Mi00ZmJjYzFkNzA1NWMyNDc4MDc5OTYxODg1N2RjNzEwMi0xNDk4NTU3OTYxNzQ4Lm1wNA==?b=479&mmsid=65565355&tm=1499247143&key=98c7e781f1145aba07cb0d6ec06f6c12&platid=3&splatid=345&playid=0&tss=no&vtype=13&cvid=2026135183914&payff=0&pip=08cc52f8b09acd3eff8bf31688ddeced&format=0&sign=mb&dname=mobile&expect=1&tag=mobile&xformat=super"));
-        clarities.add(new VideoClarity("超清", "720P", "http://play.g3proxy.lecloud.com/vod/v2/MjQ5LzM3LzIwL2xldHYtdXRzLzE0L3Zlcl8wMF8yMi0xMTA3NjQxMzkwLWF2Yy00MTk4MTAtYWFjLTQ4MDAwLTUyNjExMC0zMTU1NTY1Mi00ZmJjYzFkNzA1NWMyNDc4MDc5OTYxODg1N2RjNzEwMi0xNDk4NTU3OTYxNzQ4Lm1wNA==?b=479&mmsid=65565355&tm=1499247143&key=98c7e781f1145aba07cb0d6ec06f6c12&platid=3&splatid=345&playid=0&tss=no&vtype=13&cvid=2026135183914&payff=0&pip=08cc52f8b09acd3eff8bf31688ddeced&format=0&sign=mb&dname=mobile&expect=1&tag=mobile&xformat=super"));
-        clarities.add(new VideoClarity("蓝光", "1080P", "http://play.g3proxy.lecloud.com/vod/v2/MjQ5LzM3LzIwL2xldHYtdXRzLzE0L3Zlcl8wMF8yMi0xMTA3NjQxMzkwLWF2Yy00MTk4MTAtYWFjLTQ4MDAwLTUyNjExMC0zMTU1NTY1Mi00ZmJjYzFkNzA1NWMyNDc4MDc5OTYxODg1N2RjNzEwMi0xNDk4NTU3OTYxNzQ4Lm1wNA==?b=479&mmsid=65565355&tm=1499247143&key=98c7e781f1145aba07cb0d6ec06f6c12&platid=3&splatid=345&playid=0&tss=no&vtype=13&cvid=2026135183914&payff=0&pip=08cc52f8b09acd3eff8bf31688ddeced&format=0&sign=mb&dname=mobile&expect=1&tag=mobile&xformat=super"));
-        return clarities;
+
+### 06.在列表中播放
+
+
+
+### 08.其他重要功能Api
+- 设置视频播放器背景图,和视频标题。
+    ``` java
+    //注意,下面这个controller是指BasisVideoController
+    //设置视频背景图
+    ImageView thumb = controller.getThumb();
+    Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
+    //设置视频标题
+    controller.setTitle("视频标题");
+    ```
+- 判断是否锁屏
+    ``` java
+    //判断是否锁屏
+    boolean locked = controller.isLocked();
+    //设置是否锁屏
+    controller.setLocked(true);
+    ```
+
+
+
+### 09.播放多个视频
+- 这个举一个例子,比如同时播放两个视频,当然这种情况在app中可能比较少
+    ``` java
+    //必须设置
+    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);
+    ```
+- 那么要是页面切换到后台,如何处理多个视频的暂停功能呢?如下所示:
+    ``` java
+    @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();
     }
     ```
 
 
-### 06.在列表中播放
+### 10.VideoPlayer相关Api
+- 关于视频播放相关的api如下所示
+    ``` java
+    //暂停播放
+    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
+    ``` java
+    //判断是否处于全屏状态
+    boolean fullScreen = mVideoPlayer.isFullScreen();
+    //是否是小窗口模式
+    boolean tinyScreen = mVideoPlayer.isTinyScreen();
+    //进入全屏
+    mVideoPlayer.startFullScreen();
+    //退出全屏
+    mVideoPlayer.stopFullScreen();
+    //开启小屏
+    mVideoPlayer.startTinyScreen();
+    //退出小屏
+    mVideoPlayer.stopTinyScreen();
+    ```
+- 关于其他比如获取速度,音量,设置属性相关Api
+    ``` java
+    //VideoPlayer相关
+    VideoPlayerBuilder.Builder builder = VideoPlayerBuilder.newBuilder();
+    VideoPlayerBuilder videoPlayerBuilder = new VideoPlayerBuilder(builder);
+    //设置视频播放器的背景色
+    builder.setPlayerBackgroundColor(Color.BLACK);
+    //设置小屏的宽高
+    int[] mTinyScreenSize = {0, 0};
+    builder.setTinyScreenSize(mTinyScreenSize);
+    //是否开启AudioFocus监听, 默认开启
+    builder.setEnableAudioFocus(false);
+    mVideoPlayer.setVideoBuilder(videoPlayerBuilder);
+    //截图
+    Bitmap bitmap = mVideoPlayer.doScreenShot();
+    //移除所有播放状态监听
+    mVideoPlayer.clearOnStateChangeListeners();
+    //获取当前缓冲百分比
+    int bufferedPercentage = mVideoPlayer.getBufferedPercentage();
+    //获取当前播放器的状态
+    int currentPlayerState = mVideoPlayer.getCurrentPlayerState();
+    //获取当前的播放状态
+    int currentPlayState = mVideoPlayer.getCurrentPlayState();
+    //获取当前播放的位置
+    long currentPosition = mVideoPlayer.getCurrentPosition();
+    //获取视频总时长
+    long duration = mVideoPlayer.getDuration();
+    //获取倍速速度
+    float speed = mVideoPlayer.getSpeed();
+    //获取缓冲速度
+    long tcpSpeed = mVideoPlayer.getTcpSpeed();
+    //获取视频宽高
+    int[] videoSize = mVideoPlayer.getVideoSize();
+    //是否处于静音状态
+    boolean mute = mVideoPlayer.isMute();
+    ```
+
+
+### 11.Controller相关Api
+- Controller控制器相关的Api说明
+    ``` java
+    //设置视频背景图
+    ImageView thumb = controller.getThumb();
+    Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
+    //设置视频标题
+    controller.setTitle("视频标题");
+    //添加自定义视图。每添加一个视图,都是方式层级树的最上层
+    CustomErrorView customErrorView = new CustomErrorView(this);
+    controller.addControlComponent(customErrorView);
+    //移除控制组件
+    controller.removeControlComponent(customErrorView);
+    //移除所有的组件
+    controller.removeAllControlComponent();
+    //隐藏播放视图
+    controller.hide();
+    //显示播放视图
+    controller.show();
+    //是否开启根据屏幕方向进入/退出全屏
+    controller.setEnableOrientation(true);
+    //显示移动网络播放提示
+    controller.showNetWarning();
+    //刘海的高度
+    int cutoutHeight = controller.getCutoutHeight();
+    //是否有刘海屏
+    boolean b = controller.hasCutout();
+    //设置是否适配刘海屏
+    controller.setAdaptCutout(true);
+    //停止刷新进度
+    controller.stopProgress();
+    //开始刷新进度,注意:需在STATE_PLAYING时调用才会开始刷新进度
+    controller.startProgress();
+    //判断是否锁屏
+    boolean locked = controller.isLocked();
+    //设置是否锁屏
+    controller.setLocked(true);
+    //取消计时
+    controller.stopFadeOut();
+    //开始计时
+    controller.startFadeOut();
+    //设置播放视图自动隐藏超时
+    controller.setDismissTimeout(8);
+    //销毁
+    controller.destroy();
+    ```
+
+
+
+
+
+
+
 - 代码如下所示
     - 在recyclerView中
     ```