Prechádzať zdrojové kódy

完善视频播放器播放异常监听

杨充 4 rokov pred
rodič
commit
86bad70e06
30 zmenil súbory, kde vykonal 181 pridanie a 72 odobranie
  1. 2 4
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/list/RecyclerView2Fragment.java
  2. 9 0
      VideoKernel/src/main/java/com/yc/kernel/factory/PlayerFactory.java
  3. 20 3
      VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoMediaPlayer.java
  4. 1 1
      VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoPlayerFactory.java
  5. 1 1
      VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkPlayerFactory.java
  6. 15 9
      VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkVideoPlayer.java
  7. 16 14
      VideoKernel/src/main/java/com/yc/kernel/impl/ijk/RawDataSourceProvider.java
  8. 19 17
      VideoKernel/src/main/java/com/yc/kernel/impl/media/AndroidMediaPlayer.java
  9. 1 1
      VideoKernel/src/main/java/com/yc/kernel/impl/media/MediaPlayerFactory.java
  10. 7 1
      VideoKernel/src/main/java/com/yc/kernel/inter/VideoPlayerListener.java
  11. 11 0
      VideoKernel/src/main/java/com/yc/kernel/utils/PlayerConstant.java
  12. 11 5
      VideoPlayer/src/main/java/com/yc/video/bridge/ControlWrapper.java
  13. 6 1
      VideoPlayer/src/main/java/com/yc/video/config/ConstantKeys.java
  14. 2 0
      VideoPlayer/src/main/java/com/yc/video/controller/BaseVideoController.java
  15. 28 0
      VideoPlayer/src/main/java/com/yc/video/player/InterVideoPlayer.java
  16. 14 1
      VideoPlayer/src/main/java/com/yc/video/player/VideoPlayer.java
  17. 1 1
      VideoPlayer/src/main/java/com/yc/video/player/VideoViewManager.java
  18. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/more/CustomNetworkView.java
  19. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/more/CustomTrailersView.java
  20. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/pip/CustomFloatView.java
  21. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomBottomView.java
  22. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomCompleteView.java
  23. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomErrorView.java
  24. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomGestureView.java
  25. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomLiveControlView.java
  26. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomPrepareView.java
  27. 1 1
      VideoPlayer/src/main/java/com/yc/video/ui/view/CustomTitleView.java
  28. 4 2
      VideoPlayer/src/main/java/com/yc/video/ui/view/InterControlView.java
  29. 1 0
      read/04.视频播放器封装思路.md
  30. 2 1
      read/50.版本更新说明文档.md

+ 2 - 4
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/list/RecyclerView2Fragment.java

@@ -29,10 +29,8 @@ import com.yc.video.ui.view.BasisVideoController;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
-/**
- * RecyclerView demo
- */
 public class RecyclerView2Fragment extends Fragment {
 
     protected List<VideoInfoBean> mVideos = new ArrayList<>();
@@ -186,7 +184,7 @@ public class RecyclerView2Fragment extends Fragment {
         if (mVideoView.isFullScreen()) {
             mVideoView.stopFullScreen();
         }
-        if(getActivity().getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
+        if(Objects.requireNonNull(getActivity()).getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
             getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         }
         mCurPos = -1;

+ 9 - 0
VideoKernel/src/main/java/com/yc/kernel/factory/PlayerFactory.java

@@ -18,6 +18,15 @@ import com.yc.kernel.inter.AbstractVideoPlayer;
 public abstract class PlayerFactory<T extends AbstractVideoPlayer> {
 
     /**
+     * 使用工厂模式
+     * 抽象工厂,担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口
+     * 具体工厂,具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建具体产品对象
+     *
+     * 优点1:工厂方法用来创建所需要的产品,同时隐藏了哪种具体产品类将被实例化这一细节,
+     *       用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
+     * 优点2:加入新的产品时,比如后期新加一个阿里播放器内核,这个时候就只需要添加一个具体工厂和具体产品就可以。
+     *       系统的可扩展性也就变得非常好,完全符合“开闭原则”
+     *
      * 创建具体的内核播放器Player
      * @param context                       上下文
      * @return                              具体的player

+ 20 - 3
VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoMediaPlayer.java

@@ -32,6 +32,8 @@ import com.yc.kernel.utils.VideoLogUtils;
 
 import java.util.Map;
 
+import static com.google.android.exoplayer2.ExoPlaybackException.TYPE_SOURCE;
+
 /**
  * <pre>
  *     @author yangchong
@@ -301,8 +303,14 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
      */
     @Override
     public void setSurface(Surface surface) {
-        if (mInternalPlayer != null) {
-            mInternalPlayer.setVideoSurface(surface);
+        if (surface!=null){
+            try {
+                if (mInternalPlayer != null) {
+                    mInternalPlayer.setVideoSurface(surface);
+                }
+            } catch (Exception e) {
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
+            }
         }
     }
 
@@ -413,7 +421,16 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
     @Override
     public void onPlayerError(ExoPlaybackException error) {
         if (mPlayerEventListener != null) {
-            mPlayerEventListener.onError();
+            int type = error.type;
+            if (type == TYPE_SOURCE){
+                //错误的链接
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_SOURCE,error.getMessage());
+            } else if (type == ExoPlaybackException.TYPE_RENDERER
+                    || type == ExoPlaybackException.TYPE_UNEXPECTED
+                    || type == ExoPlaybackException.TYPE_REMOTE
+                    || type == ExoPlaybackException.TYPE_OUT_OF_MEMORY){
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,error.getMessage());
+            }
         }
     }
 

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoPlayerFactory.java

@@ -10,7 +10,7 @@ import com.yc.kernel.factory.PlayerFactory;
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
  *     desc  : exo视频播放器Factory
- *     revise:
+ *     revise: 抽象工厂具体实现类
  * </pre>
  */
 public class ExoPlayerFactory extends PlayerFactory<ExoMediaPlayer> {

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkPlayerFactory.java

@@ -24,7 +24,7 @@ import com.yc.kernel.factory.PlayerFactory;
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
  *     desc  : ijk视频播放器Factory
- *     revise:
+ *     revise: 抽象工厂具体实现类
  * </pre>
  */
 public class IjkPlayerFactory extends PlayerFactory<IjkVideoPlayer> {

+ 15 - 9
VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkVideoPlayer.java

@@ -175,7 +175,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
                 mMediaPlayer.setDataSource(mAppContext, uri, headers);
             }
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_PARSE,e.getMessage());
         }
     }
 
@@ -187,7 +187,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.setDataSource(new RawDataSourceProvider(fd));
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -197,7 +197,13 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
      */
     @Override
     public void setSurface(Surface surface) {
-        mMediaPlayer.setSurface(surface);
+        if (surface!=null){
+            try {
+                mMediaPlayer.setSurface(surface);
+            } catch (Exception e) {
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
+            }
+        }
     }
 
     /**
@@ -208,7 +214,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.prepareAsync();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -220,7 +226,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.pause();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -232,7 +238,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.start();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -244,7 +250,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.stop();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -275,7 +281,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.seekTo((int) time);
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -387,7 +393,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
     private IMediaPlayer.OnErrorListener onErrorListener = new IMediaPlayer.OnErrorListener() {
         @Override
         public boolean onError(IMediaPlayer iMediaPlayer, int framework_err, int impl_err) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,"监听异常"+ framework_err + ", extra: " + impl_err);
             VideoLogUtils.d("IjkVideoPlayer----listener---------onError ——> STATE_ERROR ———— what:" + framework_err + ", extra: " + impl_err);
             return true;
         }

+ 16 - 14
VideoKernel/src/main/java/com/yc/kernel/impl/ijk/RawDataSourceProvider.java

@@ -26,10 +26,18 @@ import java.io.InputStream;
 
 import tv.danmaku.ijk.media.player.misc.IMediaDataSource;
 
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2018/11/9
+ *     desc  : ijk视频播放器读取本地资源Source实现类
+ *     revise:
+ * </pre>
+ */
 public class RawDataSourceProvider implements IMediaDataSource {
 
     private AssetFileDescriptor mDescriptor;
-
     private byte[] mMediaBytes;
 
     public RawDataSourceProvider(AssetFileDescriptor descriptor) {
@@ -41,19 +49,18 @@ public class RawDataSourceProvider implements IMediaDataSource {
         if (position + 1 >= mMediaBytes.length) {
             return -1;
         }
-
         int length;
         if (position + size < mMediaBytes.length) {
             length = size;
         } else {
             length = (int) (mMediaBytes.length - position);
-            if (length > buffer.length)
+            if (length > buffer.length){
                 length = buffer.length;
-
+            }
             length--;
         }
+        //使用系统集合拷贝
         System.arraycopy(mMediaBytes, (int) position, buffer, offset, length);
-
         return length;
     }
 
@@ -64,39 +71,34 @@ public class RawDataSourceProvider implements IMediaDataSource {
             InputStream inputStream = mDescriptor.createInputStream();
             mMediaBytes = readBytes(inputStream);
         }
-
-
         return length;
     }
 
     @Override
     public void close() throws IOException {
-        if (mDescriptor != null)
+        if (mDescriptor != null){
             mDescriptor.close();
-
+        }
         mDescriptor = null;
         mMediaBytes = null;
     }
 
     private byte[] readBytes(InputStream inputStream) throws IOException {
         ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
-
         int bufferSize = 1024;
         byte[] buffer = new byte[bufferSize];
-
         int len;
         while ((len = inputStream.read(buffer)) != -1) {
             byteBuffer.write(buffer, 0, len);
         }
-
         return byteBuffer.toByteArray();
     }
 
     public static RawDataSourceProvider create(Context context, Uri uri) {
         try {
-            AssetFileDescriptor fileDescriptor = context.getContentResolver().openAssetFileDescriptor(uri, "r");
+            AssetFileDescriptor fileDescriptor = context.getContentResolver()
+                    .openAssetFileDescriptor(uri, "r");
             return new RawDataSourceProvider(fileDescriptor);
-
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }

+ 19 - 17
VideoKernel/src/main/java/com/yc/kernel/impl/media/AndroidMediaPlayer.java

@@ -93,7 +93,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             Uri uri = Uri.parse(path);
             mMediaPlayer.setDataSource(mAppContext, uri, headers);
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_PARSE,e.getMessage());
         }
     }
 
@@ -105,7 +105,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -117,7 +117,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.start();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -129,7 +129,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.pause();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -141,7 +141,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.stop();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -151,7 +151,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             mIsPreparing = true;
             mMediaPlayer.prepareAsync();
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -182,7 +182,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.seekTo((int) time);
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -240,10 +240,12 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
      */
     @Override
     public void setSurface(Surface surface) {
-        try {
-            mMediaPlayer.setSurface(surface);
-        } catch (Exception e) {
-            mPlayerEventListener.onError();
+        if (surface!=null){
+            try {
+                mMediaPlayer.setSurface(surface);
+            } catch (Exception e) {
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
+            }
         }
     }
 
@@ -256,7 +258,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.setDisplay(holder);
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -270,7 +272,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.setVolume(v1, v2);
         } catch (Exception e){
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -283,7 +285,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
             mMediaPlayer.setLooping(isLooping);
         } catch (Exception e){
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
     }
 
@@ -302,7 +304,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             try {
                 mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(speed));
             } catch (Exception e) {
-                mPlayerEventListener.onError();
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
             }
         }
     }
@@ -318,7 +320,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             try {
                 return mMediaPlayer.getPlaybackParams().getSpeed();
             } catch (Exception e) {
-                mPlayerEventListener.onError();
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
             }
         }
         return 1f;
@@ -337,7 +339,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
     private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,"监听异常"+ what + ", extra: " + extra);
             return true;
         }
     };

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/media/MediaPlayerFactory.java

@@ -26,7 +26,7 @@ import com.yc.kernel.factory.PlayerFactory;
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
  *     desc  : 不推荐,系统的MediaPlayer兼容性较差,建议使用IjkPlayer或者ExoPlayer
- *     revise:
+ *     revise: 抽象工厂具体实现类
  * </pre>
  */
 public class MediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> {

+ 7 - 1
VideoKernel/src/main/java/com/yc/kernel/inter/VideoPlayerListener.java

@@ -15,6 +15,8 @@ limitations under the License.
 */
 package com.yc.kernel.inter;
 
+import com.yc.kernel.utils.PlayerConstant;
+
 /**
  * <pre>
  *     @author yangchong
@@ -28,8 +30,12 @@ public interface VideoPlayerListener {
 
     /**
      * 异常
+     * 1          表示错误的链接
+     * 2          表示解析异常
+     * 3          表示其他的异常
+     * @param type                          错误类型
      */
-    void onError();
+    void onError(@PlayerConstant.ErrorType int type , String error);
 
     /**
      * 完成

+ 11 - 0
VideoKernel/src/main/java/com/yc/kernel/utils/PlayerConstant.java

@@ -54,4 +54,15 @@ public final class PlayerConstant {
         int TYPE_EXO = 3;
         int TYPE_RTC = 4;
     }
+
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ErrorType {
+        //错误的链接
+        int TYPE_SOURCE = 1;
+        //解析异常
+        int TYPE_PARSE = 2;
+        //其他异常
+        int TYPE_UNEXPECTED = 3;
+    }
+
 }

+ 11 - 5
VideoPlayer/src/main/java/com/yc/video/controller/ControlWrapper.java → VideoPlayer/src/main/java/com/yc/video/bridge/ControlWrapper.java

@@ -13,19 +13,25 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
-package com.yc.video.controller;
+package com.yc.video.bridge;
 
 import android.app.Activity;
 import android.content.pm.ActivityInfo;
 import android.graphics.Bitmap;
-
 import androidx.annotation.NonNull;
-
+import com.yc.video.controller.InterVideoController;
 import com.yc.video.player.InterVideoPlayer;
 
+
 /**
- * 此类的目的是为了在InterControlView接口实现类中既能调用VideoPlayer的api又能调用BaseVideoController的api,
- * 并对部分api做了封装,方便使用
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2018/11/9
+ *     desc  : 此类的目的是为了在InterControlView接口实现类中既能调用VideoPlayer的api又能调用BaseVideoController的api,
+ *             并对部分api做了封装,方便使用
+ *     revise:
+ * </pre>
  */
 public class ControlWrapper implements InterVideoPlayer, InterVideoController {
     

+ 6 - 1
VideoPlayer/src/main/java/com/yc/video/config/ConstantKeys.java

@@ -80,6 +80,8 @@ public final class ConstantKeys {
 
     /**
      * 播放状态,主要是指播放器的各种状态
+     * -3               解析异常
+     * -2               播放错误,网络异常
      * -1               播放错误
      * 0                播放未开始,即将进行
      * 1                播放准备中
@@ -93,6 +95,8 @@ public final class ConstantKeys {
      */
     @Retention(RetentionPolicy.SOURCE)
     public @interface CurrentState{
+        int STATE_PARSE_ERROR = -3;
+        int STATE_NETWORK_ERROR = -2;
         int STATE_ERROR = -1;
         int STATE_IDLE = 0;
         int STATE_PREPARING = 1;
@@ -108,7 +112,8 @@ public final class ConstantKeys {
     @IntDef({CurrentState.STATE_ERROR,CurrentState.STATE_IDLE,CurrentState.STATE_PREPARING,
             CurrentState.STATE_PREPARED,CurrentState.STATE_PLAYING,CurrentState.STATE_PAUSED,
             CurrentState.STATE_BUFFERING_PLAYING,CurrentState.STATE_BUFFERING_PAUSED,
-            CurrentState.STATE_COMPLETED,CurrentState.STATE_START_ABORT})
+            CurrentState.STATE_COMPLETED,CurrentState.STATE_START_ABORT,CurrentState.STATE_NETWORK_ERROR,
+            CurrentState.STATE_PARSE_ERROR})
     @Retention(RetentionPolicy.SOURCE)
     public @interface CurrentStateType{}
 

+ 2 - 0
VideoPlayer/src/main/java/com/yc/video/controller/BaseVideoController.java

@@ -31,6 +31,7 @@ import androidx.annotation.CallSuper;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.player.InterVideoPlayer;
 import com.yc.video.player.VideoViewManager;
@@ -90,6 +91,7 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
     private boolean mIsStartProgress;
 
     //保存了所有的控制组件
+    //使用LinkedHashMap有序
     protected LinkedHashMap<InterControlView, Boolean> mControlComponents = new LinkedHashMap<>();
 
     private Animation mShowAnim;

+ 28 - 0
VideoPlayer/src/main/java/com/yc/video/player/InterVideoPlayer.java

@@ -45,20 +45,48 @@ import com.yc.video.config.ConstantKeys;
  */
 public interface InterVideoPlayer {
 
+    /**
+     * 开始播放
+     */
     void start();
 
+    /**
+     * 暂停播放
+     */
     void pause();
 
+    /**
+     * 获取视频总时长
+     * @return                              long类型
+     */
     long getDuration();
 
+
+    /**
+     * 获取当前播放的位置
+     * @return                              long类型
+     */
     long getCurrentPosition();
 
+    /**
+     * 调整播放进度
+     * @param pos                           位置
+     */
     void seekTo(long pos);
 
+    /**
+     * 是否处于播放状态
+     * @return                              是否处于播放状态
+     */
     boolean isPlaying();
 
+    /**
+     * 获取当前缓冲百分比
+     * @return                              百分比
+     */
     int getBufferedPercentage();
 
+
     void startFullScreen();
 
     void stopFullScreen();

+ 14 - 1
VideoPlayer/src/main/java/com/yc/video/player/VideoPlayer.java

@@ -626,8 +626,21 @@ public class VideoPlayer<P extends AbstractVideoPlayer> extends FrameLayout
      * 视频播放出错回调
      */
     @Override
-    public void onError() {
+    public void onError(@PlayerConstant.ErrorType int type , String error) {
         mPlayerContainer.setKeepScreenOn(false);
+        if (PlayerUtils.isConnected(mContext)){
+            if (type == PlayerConstant.ErrorType.TYPE_UNEXPECTED){
+                setPlayState(ConstantKeys.CurrentState.STATE_ERROR);
+            } else if (type == PlayerConstant.ErrorType.TYPE_PARSE){
+                setPlayState(ConstantKeys.CurrentState.STATE_PARSE_ERROR);
+            } else if (type == PlayerConstant.ErrorType.TYPE_SOURCE){
+                setPlayState(ConstantKeys.CurrentState.STATE_ERROR);
+            } else {
+                setPlayState(ConstantKeys.CurrentState.STATE_ERROR);
+            }
+        } else {
+            setPlayState(ConstantKeys.CurrentState.STATE_NETWORK_ERROR);
+        }
         setPlayState(ConstantKeys.CurrentState.STATE_ERROR);
         VideoPlayerConfig config = VideoViewManager.getConfig();
         if (config!=null && config.mBuriedPointEvent!=null){

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/player/VideoViewManager.java

@@ -42,7 +42,7 @@ public class VideoViewManager {
     /**
      * VideoViewManager实例
      */
-    private static VideoViewManager sInstance;
+    private static volatile VideoViewManager sInstance;
 
     /**
      * VideoViewConfig实例

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/more/CustomNetworkView.java

@@ -24,7 +24,7 @@ import android.widget.FrameLayout;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.ui.view.InterControlView;
 
 /**

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/more/CustomTrailersView.java

@@ -24,7 +24,7 @@ import android.widget.FrameLayout;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.ui.view.InterControlView;
 
 /**

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/pip/CustomFloatView.java

@@ -30,7 +30,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 
 import com.yc.video.R;
 

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomBottomView.java

@@ -37,7 +37,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.tool.PlayerUtils;
 
 import com.yc.video.R;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomCompleteView.java

@@ -30,7 +30,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.tool.BaseToast;
 import com.yc.video.tool.PlayerUtils;
 

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomErrorView.java

@@ -28,7 +28,7 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 
 import com.yc.video.R;
 

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomGestureView.java

@@ -31,7 +31,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.controller.IGestureComponent;
 import com.yc.video.tool.PlayerUtils;
 

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomLiveControlView.java

@@ -29,7 +29,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.tool.PlayerUtils;
 
 import com.yc.video.R;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomPrepareView.java

@@ -29,7 +29,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.player.VideoViewManager;
 
 import com.yc.video.R;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/ui/view/CustomTitleView.java

@@ -34,7 +34,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.tool.PlayerUtils;
 
 import com.yc.video.R;

+ 4 - 2
VideoPlayer/src/main/java/com/yc/video/ui/view/InterControlView.java

@@ -20,7 +20,7 @@ import android.view.animation.Animation;
 
 import androidx.annotation.NonNull;
 
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 
 
 /**
@@ -29,7 +29,9 @@ import com.yc.video.controller.ControlWrapper;
  *     blog  : https://github.com/yangchong211
  *     time  : 2017/11/9
  *     desc  : 自定义控制器接口
- *     revise:
+ *     revise: 如果需要添加自定义播放器视图,则需要继承InterControlView接口
+ *             关于视频播放器播放状态和视图状态,都需要自定义视图去控制view的状态
+ *             举一个例子:比如广告视图,
  * </pre>
  */
 public interface InterControlView {

+ 1 - 0
read/04.视频播放器封装思路.md

@@ -53,6 +53,7 @@
     - 视频窗口、音频窗口、视频浮窗、音频浮窗、短视频窗口、短视频浮窗、音频控制台等多种场景播放,需要灵活切换,这个也是一个大的难点
 
 
+
 ### 03.该播放器框架特点
 - 一定要解耦合
     - 播放器内核与播放器解耦: 支持更多的播放场景、以及新的播放业务快速接入,并且不影响其他播放业务,比如后期添加阿里云播放器内核,或者腾讯播放器内核

+ 2 - 1
read/50.版本更新说明文档.md

@@ -63,7 +63,8 @@
 - 6.1.2.2 OnBufferingUpdateListener监听中,播放完成后再次播放getBufferPercentage获取的值也不准确,94到99,达不到100。因此当大于95时,手动设置成100。
 
 
-
+##### 更新于2020年12月份
+- 1.基于exo,ijk,media等不同内核视频播放器,添加播放异常区分,添加多种异常类型:播放解析异常,无网络异常,加载资源错误异常,错误连接异常,解码异常等