Răsfoiți Sursa

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

杨充 4 ani în urmă
părinte
comite
86bad70e06
30 a modificat fișierele cu 181 adăugiri și 72 ștergeri
  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.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Objects;
 
 
-/**
- * RecyclerView demo
- */
 public class RecyclerView2Fragment extends Fragment {
 public class RecyclerView2Fragment extends Fragment {
 
 
     protected List<VideoInfoBean> mVideos = new ArrayList<>();
     protected List<VideoInfoBean> mVideos = new ArrayList<>();
@@ -186,7 +184,7 @@ public class RecyclerView2Fragment extends Fragment {
         if (mVideoView.isFullScreen()) {
         if (mVideoView.isFullScreen()) {
             mVideoView.stopFullScreen();
             mVideoView.stopFullScreen();
         }
         }
-        if(getActivity().getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
+        if(Objects.requireNonNull(getActivity()).getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
             getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
             getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         }
         }
         mCurPos = -1;
         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> {
 public abstract class PlayerFactory<T extends AbstractVideoPlayer> {
 
 
     /**
     /**
+     * 使用工厂模式
+     * 抽象工厂,担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口
+     * 具体工厂,具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建具体产品对象
+     *
+     * 优点1:工厂方法用来创建所需要的产品,同时隐藏了哪种具体产品类将被实例化这一细节,
+     *       用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
+     * 优点2:加入新的产品时,比如后期新加一个阿里播放器内核,这个时候就只需要添加一个具体工厂和具体产品就可以。
+     *       系统的可扩展性也就变得非常好,完全符合“开闭原则”
+     *
      * 创建具体的内核播放器Player
      * 创建具体的内核播放器Player
      * @param context                       上下文
      * @param context                       上下文
      * @return                              具体的player
      * @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 java.util.Map;
 
 
+import static com.google.android.exoplayer2.ExoPlaybackException.TYPE_SOURCE;
+
 /**
 /**
  * <pre>
  * <pre>
  *     @author yangchong
  *     @author yangchong
@@ -301,8 +303,14 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
      */
      */
     @Override
     @Override
     public void setSurface(Surface surface) {
     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
     @Override
     public void onPlayerError(ExoPlaybackException error) {
     public void onPlayerError(ExoPlaybackException error) {
         if (mPlayerEventListener != null) {
         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
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
  *     time  : 2018/11/9
  *     desc  : exo视频播放器Factory
  *     desc  : exo视频播放器Factory
- *     revise:
+ *     revise: 抽象工厂具体实现类
  * </pre>
  * </pre>
  */
  */
 public class ExoPlayerFactory extends PlayerFactory<ExoMediaPlayer> {
 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
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
  *     time  : 2018/11/9
  *     desc  : ijk视频播放器Factory
  *     desc  : ijk视频播放器Factory
- *     revise:
+ *     revise: 抽象工厂具体实现类
  * </pre>
  * </pre>
  */
  */
 public class IjkPlayerFactory extends PlayerFactory<IjkVideoPlayer> {
 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);
                 mMediaPlayer.setDataSource(mAppContext, uri, headers);
             }
             }
         } catch (Exception e) {
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_PARSE,e.getMessage());
         }
         }
     }
     }
 
 
@@ -187,7 +187,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.setDataSource(new RawDataSourceProvider(fd));
             mMediaPlayer.setDataSource(new RawDataSourceProvider(fd));
         } catch (Exception e) {
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -197,7 +197,13 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
      */
      */
     @Override
     @Override
     public void setSurface(Surface surface) {
     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 {
         try {
             mMediaPlayer.prepareAsync();
             mMediaPlayer.prepareAsync();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -220,7 +226,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.pause();
             mMediaPlayer.pause();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -232,7 +238,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.start();
             mMediaPlayer.start();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -244,7 +250,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.stop();
             mMediaPlayer.stop();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -275,7 +281,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.seekTo((int) time);
             mMediaPlayer.seekTo((int) time);
         } catch (IllegalStateException e) {
         } 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() {
     private IMediaPlayer.OnErrorListener onErrorListener = new IMediaPlayer.OnErrorListener() {
         @Override
         @Override
         public boolean onError(IMediaPlayer iMediaPlayer, int framework_err, int impl_err) {
         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);
             VideoLogUtils.d("IjkVideoPlayer----listener---------onError ——> STATE_ERROR ———— what:" + framework_err + ", extra: " + impl_err);
             return true;
             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;
 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 {
 public class RawDataSourceProvider implements IMediaDataSource {
 
 
     private AssetFileDescriptor mDescriptor;
     private AssetFileDescriptor mDescriptor;
-
     private byte[] mMediaBytes;
     private byte[] mMediaBytes;
 
 
     public RawDataSourceProvider(AssetFileDescriptor descriptor) {
     public RawDataSourceProvider(AssetFileDescriptor descriptor) {
@@ -41,19 +49,18 @@ public class RawDataSourceProvider implements IMediaDataSource {
         if (position + 1 >= mMediaBytes.length) {
         if (position + 1 >= mMediaBytes.length) {
             return -1;
             return -1;
         }
         }
-
         int length;
         int length;
         if (position + size < mMediaBytes.length) {
         if (position + size < mMediaBytes.length) {
             length = size;
             length = size;
         } else {
         } else {
             length = (int) (mMediaBytes.length - position);
             length = (int) (mMediaBytes.length - position);
-            if (length > buffer.length)
+            if (length > buffer.length){
                 length = buffer.length;
                 length = buffer.length;
-
+            }
             length--;
             length--;
         }
         }
+        //使用系统集合拷贝
         System.arraycopy(mMediaBytes, (int) position, buffer, offset, length);
         System.arraycopy(mMediaBytes, (int) position, buffer, offset, length);
-
         return length;
         return length;
     }
     }
 
 
@@ -64,39 +71,34 @@ public class RawDataSourceProvider implements IMediaDataSource {
             InputStream inputStream = mDescriptor.createInputStream();
             InputStream inputStream = mDescriptor.createInputStream();
             mMediaBytes = readBytes(inputStream);
             mMediaBytes = readBytes(inputStream);
         }
         }
-
-
         return length;
         return length;
     }
     }
 
 
     @Override
     @Override
     public void close() throws IOException {
     public void close() throws IOException {
-        if (mDescriptor != null)
+        if (mDescriptor != null){
             mDescriptor.close();
             mDescriptor.close();
-
+        }
         mDescriptor = null;
         mDescriptor = null;
         mMediaBytes = null;
         mMediaBytes = null;
     }
     }
 
 
     private byte[] readBytes(InputStream inputStream) throws IOException {
     private byte[] readBytes(InputStream inputStream) throws IOException {
         ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
         ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
-
         int bufferSize = 1024;
         int bufferSize = 1024;
         byte[] buffer = new byte[bufferSize];
         byte[] buffer = new byte[bufferSize];
-
         int len;
         int len;
         while ((len = inputStream.read(buffer)) != -1) {
         while ((len = inputStream.read(buffer)) != -1) {
             byteBuffer.write(buffer, 0, len);
             byteBuffer.write(buffer, 0, len);
         }
         }
-
         return byteBuffer.toByteArray();
         return byteBuffer.toByteArray();
     }
     }
 
 
     public static RawDataSourceProvider create(Context context, Uri uri) {
     public static RawDataSourceProvider create(Context context, Uri uri) {
         try {
         try {
-            AssetFileDescriptor fileDescriptor = context.getContentResolver().openAssetFileDescriptor(uri, "r");
+            AssetFileDescriptor fileDescriptor = context.getContentResolver()
+                    .openAssetFileDescriptor(uri, "r");
             return new RawDataSourceProvider(fileDescriptor);
             return new RawDataSourceProvider(fileDescriptor);
-
         } catch (FileNotFoundException e) {
         } catch (FileNotFoundException e) {
             e.printStackTrace();
             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);
             Uri uri = Uri.parse(path);
             mMediaPlayer.setDataSource(mAppContext, uri, headers);
             mMediaPlayer.setDataSource(mAppContext, uri, headers);
         } catch (Exception e) {
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_PARSE,e.getMessage());
         }
         }
     }
     }
 
 
@@ -105,7 +105,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
             mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
         } catch (Exception e) {
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -117,7 +117,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.start();
             mMediaPlayer.start();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -129,7 +129,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.pause();
             mMediaPlayer.pause();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -141,7 +141,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.stop();
             mMediaPlayer.stop();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -151,7 +151,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             mIsPreparing = true;
             mIsPreparing = true;
             mMediaPlayer.prepareAsync();
             mMediaPlayer.prepareAsync();
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -182,7 +182,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.seekTo((int) time);
             mMediaPlayer.seekTo((int) time);
         } catch (IllegalStateException e) {
         } catch (IllegalStateException e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -240,10 +240,12 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
      */
      */
     @Override
     @Override
     public void setSurface(Surface surface) {
     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 {
         try {
             mMediaPlayer.setDisplay(holder);
             mMediaPlayer.setDisplay(holder);
         } catch (Exception e) {
         } catch (Exception e) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -270,7 +272,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.setVolume(v1, v2);
             mMediaPlayer.setVolume(v1, v2);
         } catch (Exception e){
         } catch (Exception e){
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -283,7 +285,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
         try {
         try {
             mMediaPlayer.setLooping(isLooping);
             mMediaPlayer.setLooping(isLooping);
         } catch (Exception e){
         } catch (Exception e){
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
         }
         }
     }
     }
 
 
@@ -302,7 +304,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             try {
             try {
                 mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(speed));
                 mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(speed));
             } catch (Exception e) {
             } catch (Exception e) {
-                mPlayerEventListener.onError();
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
             }
             }
         }
         }
     }
     }
@@ -318,7 +320,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             try {
             try {
                 return mMediaPlayer.getPlaybackParams().getSpeed();
                 return mMediaPlayer.getPlaybackParams().getSpeed();
             } catch (Exception e) {
             } catch (Exception e) {
-                mPlayerEventListener.onError();
+                mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
             }
             }
         }
         }
         return 1f;
         return 1f;
@@ -337,7 +339,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
     private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
     private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
         @Override
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
         public boolean onError(MediaPlayer mp, int what, int extra) {
-            mPlayerEventListener.onError();
+            mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,"监听异常"+ what + ", extra: " + extra);
             return true;
             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
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
  *     time  : 2018/11/9
  *     desc  : 不推荐,系统的MediaPlayer兼容性较差,建议使用IjkPlayer或者ExoPlayer
  *     desc  : 不推荐,系统的MediaPlayer兼容性较差,建议使用IjkPlayer或者ExoPlayer
- *     revise:
+ *     revise: 抽象工厂具体实现类
  * </pre>
  * </pre>
  */
  */
 public class MediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> {
 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;
 package com.yc.kernel.inter;
 
 
+import com.yc.kernel.utils.PlayerConstant;
+
 /**
 /**
  * <pre>
  * <pre>
  *     @author yangchong
  *     @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_EXO = 3;
         int TYPE_RTC = 4;
         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
 See the License for the specific language governing permissions and
 limitations under the License.
 limitations under the License.
 */
 */
-package com.yc.video.controller;
+package com.yc.video.bridge;
 
 
 import android.app.Activity;
 import android.app.Activity;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ActivityInfo;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.NonNull;
-
+import com.yc.video.controller.InterVideoController;
 import com.yc.video.player.InterVideoPlayer;
 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 {
 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               播放错误
      * -1               播放错误
      * 0                播放未开始,即将进行
      * 0                播放未开始,即将进行
      * 1                播放准备中
      * 1                播放准备中
@@ -93,6 +95,8 @@ public final class ConstantKeys {
      */
      */
     @Retention(RetentionPolicy.SOURCE)
     @Retention(RetentionPolicy.SOURCE)
     public @interface CurrentState{
     public @interface CurrentState{
+        int STATE_PARSE_ERROR = -3;
+        int STATE_NETWORK_ERROR = -2;
         int STATE_ERROR = -1;
         int STATE_ERROR = -1;
         int STATE_IDLE = 0;
         int STATE_IDLE = 0;
         int STATE_PREPARING = 1;
         int STATE_PREPARING = 1;
@@ -108,7 +112,8 @@ public final class ConstantKeys {
     @IntDef({CurrentState.STATE_ERROR,CurrentState.STATE_IDLE,CurrentState.STATE_PREPARING,
     @IntDef({CurrentState.STATE_ERROR,CurrentState.STATE_IDLE,CurrentState.STATE_PREPARING,
             CurrentState.STATE_PREPARED,CurrentState.STATE_PLAYING,CurrentState.STATE_PAUSED,
             CurrentState.STATE_PREPARED,CurrentState.STATE_PLAYING,CurrentState.STATE_PAUSED,
             CurrentState.STATE_BUFFERING_PLAYING,CurrentState.STATE_BUFFERING_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)
     @Retention(RetentionPolicy.SOURCE)
     public @interface CurrentStateType{}
     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.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Nullable;
 
 
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.player.InterVideoPlayer;
 import com.yc.video.player.InterVideoPlayer;
 import com.yc.video.player.VideoViewManager;
 import com.yc.video.player.VideoViewManager;
@@ -90,6 +91,7 @@ public abstract class BaseVideoController extends FrameLayout implements InterVi
     private boolean mIsStartProgress;
     private boolean mIsStartProgress;
 
 
     //保存了所有的控制组件
     //保存了所有的控制组件
+    //使用LinkedHashMap有序
     protected LinkedHashMap<InterControlView, Boolean> mControlComponents = new LinkedHashMap<>();
     protected LinkedHashMap<InterControlView, Boolean> mControlComponents = new LinkedHashMap<>();
 
 
     private Animation mShowAnim;
     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 {
 public interface InterVideoPlayer {
 
 
+    /**
+     * 开始播放
+     */
     void start();
     void start();
 
 
+    /**
+     * 暂停播放
+     */
     void pause();
     void pause();
 
 
+    /**
+     * 获取视频总时长
+     * @return                              long类型
+     */
     long getDuration();
     long getDuration();
 
 
+
+    /**
+     * 获取当前播放的位置
+     * @return                              long类型
+     */
     long getCurrentPosition();
     long getCurrentPosition();
 
 
+    /**
+     * 调整播放进度
+     * @param pos                           位置
+     */
     void seekTo(long pos);
     void seekTo(long pos);
 
 
+    /**
+     * 是否处于播放状态
+     * @return                              是否处于播放状态
+     */
     boolean isPlaying();
     boolean isPlaying();
 
 
+    /**
+     * 获取当前缓冲百分比
+     * @return                              百分比
+     */
     int getBufferedPercentage();
     int getBufferedPercentage();
 
 
+
     void startFullScreen();
     void startFullScreen();
 
 
     void stopFullScreen();
     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
     @Override
-    public void onError() {
+    public void onError(@PlayerConstant.ErrorType int type , String error) {
         mPlayerContainer.setKeepScreenOn(false);
         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);
         setPlayState(ConstantKeys.CurrentState.STATE_ERROR);
         VideoPlayerConfig config = VideoViewManager.getConfig();
         VideoPlayerConfig config = VideoViewManager.getConfig();
         if (config!=null && config.mBuriedPointEvent!=null){
         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实例
      * VideoViewManager实例
      */
      */
-    private static VideoViewManager sInstance;
+    private static volatile VideoViewManager sInstance;
 
 
     /**
     /**
      * VideoViewConfig实例
      * 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.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Nullable;
 
 
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.ui.view.InterControlView;
 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.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Nullable;
 
 
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.ui.view.InterControlView;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 
 
 import com.yc.video.R;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 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.tool.PlayerUtils;
 
 
 import com.yc.video.R;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 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.BaseToast;
 import com.yc.video.tool.PlayerUtils;
 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 android.widget.TextView;
 
 
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.config.ConstantKeys;
-import com.yc.video.controller.ControlWrapper;
+import com.yc.video.bridge.ControlWrapper;
 
 
 import com.yc.video.R;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 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.controller.IGestureComponent;
 import com.yc.video.tool.PlayerUtils;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 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.tool.PlayerUtils;
 
 
 import com.yc.video.R;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 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.player.VideoViewManager;
 
 
 import com.yc.video.R;
 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 androidx.annotation.Nullable;
 
 
 import com.yc.video.config.ConstantKeys;
 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.tool.PlayerUtils;
 
 
 import com.yc.video.R;
 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 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
  *     blog  : https://github.com/yangchong211
  *     time  : 2017/11/9
  *     time  : 2017/11/9
  *     desc  : 自定义控制器接口
  *     desc  : 自定义控制器接口
- *     revise:
+ *     revise: 如果需要添加自定义播放器视图,则需要继承InterControlView接口
+ *             关于视频播放器播放状态和视图状态,都需要自定义视图去控制view的状态
+ *             举一个例子:比如广告视图,
  * </pre>
  * </pre>
  */
  */
 public interface InterControlView {
 public interface InterControlView {

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

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

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

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