Commit 146a809a9b7deb29a1e120326a32b663b8e3de7c

Authored by YangShuai
1 parent 97ca2a02

1 视频封装增加详细的错误信息回调

2 修改播放器初始化逻辑
Showing 28 changed files with 430 additions and 77 deletions
app/strike/src/main/AndroidManifest.xml
... ... @@ -9,7 +9,7 @@
9 9 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
10 10  
11 11 <application
12   - android:name="com.cnlive.strike.demo.exoplayer.demo.DemoApplication"
  12 + android:name="com.cnlive.strike.DemoApplication"
13 13 android:allowBackup="true"
14 14 android:icon="@mipmap/ic_launcher"
15 15 android:label="@string/app_name"
... ...
app/strike/src/main/java/com/cnlive/strike/demo/exoplayer/demo/DemoApplication.java renamed to app/strike/src/main/java/com/cnlive/strike/DemoApplication.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package com.cnlive.strike.demo.exoplayer.demo;
  16 +package com.cnlive.strike;
17 17  
18 18 import android.app.Application;
19 19  
... ... @@ -23,6 +23,7 @@ import com.baidu.mapapi.SDKInitializer;
23 23 import com.cnlive.cloud.user.auth.UserService;
24 24 import com.cnlive.core.libs.base.application.AppConfig;
25 25 import com.cnlive.core.libs.base.application.BaseApplication;
  26 +import com.cnlive.strike.demo.exoplayer.demo.DownloadTracker;
26 27 import com.google.android.exoplayer2.BuildConfig;
27 28 import com.google.android.exoplayer2.DefaultRenderersFactory;
28 29 import com.google.android.exoplayer2.RenderersFactory;
... ... @@ -45,6 +46,13 @@ import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
45 46 import com.google.android.exoplayer2.upstream.cache.SimpleCache;
46 47 import com.google.android.exoplayer2.util.Log;
47 48 import com.google.android.exoplayer2.util.Util;
  49 +import com.libs.video.video.exoplayer.play.VideoViewConfig;
  50 +import com.libs.video.video.exoplayer.play.VideoViewManager;
  51 +import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaPlayerFactory;
  52 +import com.libs.video.video.exoplayer.render.surface.SurfaceRenderViewFactory;
  53 +import com.libs.video.video.exoplayer.render.texture.TextureRenderView;
  54 +import com.libs.video.video.exoplayer.render.texture.TextureRenderViewFactory;
  55 +
48 56 import java.io.File;
49 57 import java.io.IOException;
50 58  
... ... @@ -87,6 +95,21 @@ public class DemoApplication extends BaseApplication {
87 95 com.cnlive.cloud.BuildConfig.SHARE_DOWNLOAD, com.cnlive.cloud.BuildConfig.SHARE_ICON, com.cnlive.cloud.BuildConfig.PAY_ACCOUNT,
88 96 com.cnlive.cloud.BuildConfig.SHARE_TITLE, com.cnlive.cloud.BuildConfig.SHARE_SUBTITLE, com.cnlive.cloud.BuildConfig.REPORT_URL,
89 97 com.cnlive.cloud.BuildConfig.BAIDU_MAP_APP_KEY, com.cnlive.cloud.BuildConfig.SHOP_PATH);
  98 +
  99 + //播放器配置,注意:此为全局配置,按需开启
  100 + VideoViewManager.setConfig(VideoViewConfig.newBuilder()
  101 + .setLogEnabled(com.cnlive.cloud.BuildConfig.DEBUG)//调试的时候请打开日志,方便排错
  102 +// .setPlayerFactory(IjkPlayerFactory.create())
  103 +// .setPlayerFactory(ThunderMediaPlayerFactory.create())
  104 + .setPlayerFactory(ExoMediaPlayerFactory.create())
  105 + .setRenderViewFactory(TextureRenderViewFactory.create())
  106 + .setEnableOrientation(true)
  107 +// .setEnableAudioFocus(false)
  108 +// .setScreenScaleType(VideoView.SCREEN_SCALE_MATCH_PARENT)
  109 +// .setAdaptCutout(false)
  110 +// .setPlayOnMobileNetwork(true)
  111 +// .setProgressManager(new ProgressManagerImpl())
  112 + .build());
90 113 // if (AppConfig.isDebug()) {
91 114 // Constant.SERVICE_ID = 213511;
92 115 // } else {
... ...
app/strike/src/main/java/com/cnlive/strike/MyApp.java
... ... @@ -7,6 +7,10 @@ import com.cnlive.cloud.BuildConfig;
7 7 import com.cnlive.cloud.user.auth.UserService;
8 8 import com.cnlive.core.libs.base.application.AppConfig;
9 9 import com.cnlive.core.libs.base.application.BaseApplication;
  10 +import com.libs.video.video.exoplayer.play.VideoViewConfig;
  11 +import com.libs.video.video.exoplayer.play.VideoViewManager;
  12 +import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaPlayerFactory;
  13 +import com.libs.video.video.exoplayer.render.surface.SurfaceRenderViewFactory;
10 14  
11 15 public class MyApp extends BaseApplication {
12 16 @Override
... ... @@ -19,6 +23,21 @@ public class MyApp extends BaseApplication {
19 23 BuildConfig.SHARE_DOWNLOAD, BuildConfig.SHARE_ICON, BuildConfig.PAY_ACCOUNT,
20 24 BuildConfig.SHARE_TITLE, BuildConfig.SHARE_SUBTITLE, BuildConfig.REPORT_URL,
21 25 BuildConfig.BAIDU_MAP_APP_KEY, BuildConfig.SHOP_PATH);
  26 +
  27 + //播放器配置,注意:此为全局配置,按需开启
  28 + VideoViewManager.setConfig(VideoViewConfig.newBuilder()
  29 + .setLogEnabled(BuildConfig.DEBUG)//调试的时候请打开日志,方便排错
  30 +// .setPlayerFactory(IjkPlayerFactory.create())
  31 +// .setPlayerFactory(ThunderMediaPlayerFactory.create())
  32 + .setPlayerFactory(ExoMediaPlayerFactory.create())
  33 + .setRenderViewFactory(SurfaceRenderViewFactory.create())
  34 + .setEnableOrientation(true)
  35 +// .setEnableAudioFocus(false)
  36 +// .setScreenScaleType(VideoView.SCREEN_SCALE_MATCH_PARENT)
  37 +// .setAdaptCutout(false)
  38 +// .setPlayOnMobileNetwork(true)
  39 +// .setProgressManager(new ProgressManagerImpl())
  40 + .build());
22 41 initARouter();
23 42 // if (AppConfig.isDebug()) {
24 43 // Constant.SERVICE_ID = 213511;
... ...
app/strike/src/main/java/com/cnlive/strike/demo/activity/ExoPlayerActivity.java
... ... @@ -17,6 +17,7 @@ import com.google.android.exoplayer2.source.hls.HlsMediaSource;
17 17 import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
18 18 import com.google.android.exoplayer2.util.Util;
19 19 import com.google.android.exoplayer2.video.VideoListener;
  20 +import com.libs.video.video.exoplayer.component.DefaultErrorView;
20 21 import com.libs.video.video.exoplayer.play.CNVideoView;
21 22 import com.libs.video.video.test.VideoPlayer;
22 23 import com.libs.video.video.exoplayer.component.DefaultAdControlView;
... ... @@ -75,20 +76,9 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
75 76 // player.addListener(this);
76 77 // // Prepare the player with the source.
77 78 player.prepare(hlsMediaSource);
78   - //播放器配置,注意:此为全局配置,按需开启
79   - VideoViewManager.setConfig(VideoViewConfig.newBuilder()
80   - .setLogEnabled(BuildConfig.DEBUG)//调试的时候请打开日志,方便排错
81   -// .setPlayerFactory(IjkPlayerFactory.create())
82   -// .setPlayerFactory(ThunderMediaPlayerFactory.create())
83   - .setPlayerFactory(ExoMediaPlayerFactory.create())
84   - .setRenderViewFactory(SurfaceRenderViewFactory.create())
85   - .setEnableOrientation(true)
86   -// .setEnableAudioFocus(false)
87   -// .setScreenScaleType(VideoView.SCREEN_SCALE_MATCH_PARENT)
88   -// .setAdaptCutout(false)
89   -// .setPlayOnMobileNetwork(true)
90   -// .setProgressManager(new ProgressManagerImpl())
91   - .build());
  79 +
  80 +
  81 +
92 82 mController = new StandardVideoController(this);
93 83 DefaultAdControlView adControlView = new DefaultAdControlView(this);
94 84 adControlView.setListener(new DefaultAdControlView.AdControlListener() {
... ... @@ -102,7 +92,9 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
102 92 playVideo();
103 93 }
104 94 });
105   - mController.addControlComponent(adControlView);
  95 + DefaultErrorView errorView=new DefaultErrorView(this);
  96 + mController.addControlComponent(adControlView, errorView);
  97 + //直播
106 98 binding.playerView.setUrl("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");
107 99 binding.playerView.setVideoController(mController);
108 100 binding.playerView.start();
... ... @@ -154,14 +146,16 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
154 146 private void playVideo() {
155 147 binding.playerView.release();
156 148 mController.removeAllControlComponent();
157   - mController.addDefaultControlComponent("正片", false);
  149 + mController.addDefaultControlComponent("正片", true);
158 150 //重新设置数据
159   - List<String> list = new ArrayList<>();
160   - list.add("http://sbslive.cnrmobile.com/storage/storage4/76/23/10/14de52115893fb5371b7e064f910ab7b.3gp");
161   - list.add("https://qq.com-ok-qq.com/20191005/24249_f5e36323/index.m3u8");
162   - list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");
163   - list.add("http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8");
164   - binding.playerView.setDataSource(list);
  151 +// List<String> list = new ArrayList<>();
  152 +// list.add("http://sbslive.cnrmobile.com/storage/storage4/76/23/10/14de52115893fb5371b7e064f910ab7b.3gp");
  153 +// list.add("https://qq.com-ok-qq.com/20191005/24249_f5e36323/index.m3u8");
  154 +// list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");
  155 +// list.add("http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8");
  156 +// binding.playerView.setDataSource(list);
  157 + binding.playerView.setUrl("rtmp://tyzg.rtmps2.cnlive.com/live-tyzg-577/577_999");
  158 +
165 159 //开始播放
166 160 binding.playerView.start();
167 161 }
... ...
app/strike/src/main/java/com/cnlive/strike/demo/exoplayer/demo/DemoDownloadService.java
... ... @@ -18,6 +18,7 @@ package com.cnlive.strike.demo.exoplayer.demo;
18 18 import android.app.Notification;
19 19  
20 20 import com.cnlive.cloud.R;
  21 +import com.cnlive.strike.DemoApplication;
21 22 import com.google.android.exoplayer2.offline.Download;
22 23 import com.google.android.exoplayer2.offline.DownloadManager;
23 24 import com.google.android.exoplayer2.offline.DownloadService;
... ...
app/strike/src/main/java/com/cnlive/strike/demo/exoplayer/demo/PlayerActivity.java
... ... @@ -33,6 +33,7 @@ import androidx.annotation.Nullable;
33 33 import androidx.appcompat.app.AppCompatActivity;
34 34  
35 35 import com.cnlive.cloud.R;
  36 +import com.cnlive.strike.DemoApplication;
36 37 import com.google.android.exoplayer2.C;
37 38 import com.google.android.exoplayer2.C.ContentType;
38 39 import com.google.android.exoplayer2.ExoPlaybackException;
... ...
app/strike/src/main/java/com/cnlive/strike/demo/exoplayer/demo/SampleChooserActivity.java
... ... @@ -38,6 +38,7 @@ import androidx.annotation.Nullable;
38 38 import androidx.appcompat.app.AppCompatActivity;
39 39  
40 40 import com.cnlive.cloud.R;
  41 +import com.cnlive.strike.DemoApplication;
41 42 import com.google.android.exoplayer2.ParserException;
42 43 import com.google.android.exoplayer2.RenderersFactory;
43 44 import com.google.android.exoplayer2.offline.DownloadService;
... ... @@ -55,7 +56,7 @@ import java.util.ArrayList;
55 56 import java.util.Arrays;
56 57 import java.util.Collections;
57 58 import java.util.List;
58   -import com.cnlive.strike.demo.exoplayer.demo.Sample;
  59 +
59 60 /** An activity for selecting from a list of media samples. */
60 61 public class SampleChooserActivity extends AppCompatActivity
61 62 implements DownloadTracker.Listener, OnChildClickListener {
... ...
app/strike/src/main/res/layout/activity_explayer.xml
... ... @@ -4,7 +4,7 @@
4 4 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
5 5 android:layout_width="match_parent"
6 6 android:layout_height="match_parent"
7   - android:background="@color/black"
  7 + android:background="@color/white"
8 8 android:orientation="vertical">
9 9  
10 10 <!-- <com.libs.video.video.test.CNLiveVideoView-->
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/PlayErrorException.java 0 → 100644
  1 +package com.libs.video.video.exoplayer;
  2 +
  3 +import android.media.MediaPlayer;
  4 +import android.text.TextUtils;
  5 +
  6 +import androidx.annotation.IntDef;
  7 +
  8 +import com.cnlive.core.libs.base.util.StatusBarConfig;
  9 +
  10 +import java.lang.annotation.Retention;
  11 +import java.lang.annotation.RetentionPolicy;
  12 +
  13 +/**
  14 + * 播放异常
  15 + */
  16 +public class PlayErrorException extends Exception {
  17 + public static final int TYPE_NETWORK_ERROR = 0;//网络错误
  18 + public static final int TYPE_SOURCE_ERROR = 1;//资源错误
  19 + public static final int TYPE_OUT_OF_MEMORY = 2;//内存溢出
  20 + public static final int TYPE_UNEXPECTED_ERROR = 3;//未知错误
  21 + public static final int TYPE_RENDERER_ERROR = 4;//渲染异常
  22 + public static final int TYPE_MediaPlayer_IOException = 5;
  23 + public static final int TYPE_MediaPlayer_IllegalArgumentException = 6;
  24 + public static final int TYPE_MediaPlayer_SecurityException = 7;
  25 + public static final int TYPE_MediaPlayer_IllegalStateException = 8;
  26 + public static final int TYPE_MediaPlayer_unknownException = 9;
  27 + public static final int TYPE_MediaPlayer_ON_ERROR = 10;
  28 +
  29 +
  30 + private int errorType;//错误类型
  31 + private String errorMsg;//错误信息
  32 +
  33 +
  34 + private MediaPlayer mediaPlayer;
  35 + private int mediaPlayer_what;
  36 + private int mediaPlayer_extra;
  37 +
  38 +
  39 + @IntDef({TYPE_NETWORK_ERROR, TYPE_SOURCE_ERROR, TYPE_OUT_OF_MEMORY, TYPE_UNEXPECTED_ERROR, TYPE_RENDERER_ERROR,
  40 + TYPE_MediaPlayer_IOException, TYPE_MediaPlayer_IllegalArgumentException, TYPE_MediaPlayer_SecurityException,
  41 + TYPE_MediaPlayer_IllegalStateException, TYPE_MediaPlayer_unknownException, TYPE_MediaPlayer_ON_ERROR})
  42 + @Retention(RetentionPolicy.SOURCE)
  43 + public @interface Type {
  44 + }
  45 +
  46 + public PlayErrorException() {
  47 + }
  48 +
  49 + public PlayErrorException(@PlayErrorException.Type int errorType, String errorMsg) {
  50 + this.errorType = errorType;
  51 + this.errorMsg = errorMsg;
  52 + }
  53 +
  54 + public int getErrorType() {
  55 + return errorType;
  56 + }
  57 +
  58 + public void setErrorType(int errorType) {
  59 + this.errorType = errorType;
  60 + }
  61 +
  62 + public String getErrorMsg() {
  63 + if (!TextUtils.isEmpty(errorMsg)) {
  64 + return errorMsg;
  65 + }
  66 + return "";
  67 + }
  68 +
  69 + public void setErrorMsg(String errorMsg) {
  70 + this.errorMsg = errorMsg;
  71 + }
  72 +
  73 + public MediaPlayer getMediaPlayer() {
  74 + return mediaPlayer;
  75 + }
  76 +
  77 + public void setMediaPlayer(MediaPlayer mediaPlayer) {
  78 + this.mediaPlayer = mediaPlayer;
  79 + }
  80 +
  81 + public int getMediaPlayer_what() {
  82 + return mediaPlayer_what;
  83 + }
  84 +
  85 + public void setMediaPlayer_what(int mediaPlayer_what) {
  86 + this.mediaPlayer_what = mediaPlayer_what;
  87 + }
  88 +
  89 + public int getMediaPlayer_extra() {
  90 + return mediaPlayer_extra;
  91 + }
  92 +
  93 + public void setMediaPlayer_extra(int mediaPlayer_extra) {
  94 + this.mediaPlayer_extra = mediaPlayer_extra;
  95 + }
  96 +}
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultAdControlView.java
... ... @@ -12,6 +12,7 @@ import android.widget.TextView;
12 12  
13 13  
14 14 import com.cnlive.cloud.video.R;
  15 +import com.libs.video.video.exoplayer.PlayErrorException;
15 16 import com.libs.video.video.exoplayer.controller.ControlWrapper;
16 17 import com.libs.video.video.exoplayer.controller.IControlComponent;
17 18 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -82,6 +83,9 @@ public class DefaultAdControlView extends FrameLayout implements IControlCompone
82 83  
83 84 }
84 85  
  86 + /**
  87 + * @param playState
  88 + */
85 89 @Override
86 90 public void onPlayStateChanged(int playState) {
87 91 switch (playState) {
... ... @@ -92,6 +96,8 @@ public class DefaultAdControlView extends FrameLayout implements IControlCompone
92 96 case CNVideoView.STATE_PAUSED:
93 97 mPlayButton.setSelected(false);
94 98 break;
  99 + case CNVideoView.STATE_ERROR:
  100 + break;
95 101 }
96 102 }
97 103  
... ... @@ -123,6 +129,11 @@ public class DefaultAdControlView extends FrameLayout implements IControlCompone
123 129 }
124 130  
125 131 @Override
  132 + public void onPlayError(PlayErrorException exception) {
  133 +
  134 + }
  135 +
  136 + @Override
126 137 public void onClick(View v) {
127 138 int id = v.getId();
128 139 if (id == R.id.back | id == R.id.fullscreen) {
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultCompleteView.java
... ... @@ -11,6 +11,7 @@ import android.widget.FrameLayout;
11 11 import android.widget.ImageView;
12 12  
13 13 import com.cnlive.cloud.video.R;
  14 +import com.libs.video.video.exoplayer.PlayErrorException;
14 15 import com.libs.video.video.exoplayer.controller.ControlWrapper;
15 16 import com.libs.video.video.exoplayer.controller.IControlComponent;
16 17 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -125,4 +126,9 @@ public class DefaultCompleteView extends FrameLayout implements IControlComponen
125 126 public void onLockStateChanged(boolean isLock) {
126 127  
127 128 }
  129 +
  130 + @Override
  131 + public void onPlayError(PlayErrorException exception) {
  132 +
  133 + }
128 134 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultErrorView.java
... ... @@ -2,16 +2,22 @@ package com.libs.video.video.exoplayer.component;
2 2  
3 3 import android.content.Context;
4 4 import android.util.AttributeSet;
  5 +import android.util.Log;
5 6 import android.view.LayoutInflater;
6 7 import android.view.MotionEvent;
7 8 import android.view.View;
8 9 import android.view.ViewConfiguration;
9 10 import android.view.animation.Animation;
  11 +import android.widget.Button;
10 12 import android.widget.LinearLayout;
  13 +import android.widget.TextView;
11 14  
12 15 import com.cnlive.cloud.video.R;
  16 +import com.cnlive.core.libs.base.util.NetworkUtil;
  17 +import com.libs.video.video.exoplayer.PlayErrorException;
13 18 import com.libs.video.video.exoplayer.controller.ControlWrapper;
14 19 import com.libs.video.video.exoplayer.controller.IControlComponent;
  20 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
15 21 import com.libs.video.video.exoplayer.play.CNVideoView;
16 22  
17 23 import androidx.annotation.NonNull;
... ... @@ -24,8 +30,10 @@ public class DefaultErrorView extends LinearLayout implements IControlComponent
24 30  
25 31 private float mDownX;
26 32 private float mDownY;
27   -
28   - private ControlWrapper mControlWrapper;
  33 + private Button btnRetry;
  34 + private TextView tvMessage;
  35 + private ControlWrapper mControlWrapper;//公共控制接口
  36 + private String TAG = this.getClass().getName();
29 37  
30 38 public DefaultErrorView(Context context) {
31 39 this(context, null);
... ... @@ -42,7 +50,9 @@ public class DefaultErrorView extends LinearLayout implements IControlComponent
42 50 {
43 51 setVisibility(GONE);
44 52 LayoutInflater.from(getContext()).inflate(R.layout.cnvideo_layout_error_view, this, true);
45   - findViewById(R.id.status_btn).setOnClickListener(new OnClickListener() {
  53 + btnRetry = findViewById(R.id.btn_retry);
  54 + tvMessage=findViewById(R.id.tv_message);
  55 + btnRetry.setOnClickListener(new OnClickListener() {
46 56 @Override
47 57 public void onClick(View v) {
48 58 setVisibility(GONE);
... ... @@ -62,14 +72,11 @@ public class DefaultErrorView extends LinearLayout implements IControlComponent
62 72 return this;
63 73 }
64 74  
65   - @Override
66   - public void onVisibilityChanged(boolean isVisible, Animation anim) {
67   -
68   - }
69 75  
70 76 @Override
71 77 public void onPlayStateChanged(int playState) {
72 78 if (playState == CNVideoView.STATE_ERROR) {
  79 + //将view的z轴改变,置于父view的最上方。这个方法会将view从父view中移除,再添加到父view中。
73 80 bringToFront();
74 81 setVisibility(VISIBLE);
75 82 } else if (playState == CNVideoView.STATE_IDLE) {
... ... @@ -77,20 +84,6 @@ public class DefaultErrorView extends LinearLayout implements IControlComponent
77 84 }
78 85 }
79 86  
80   - @Override
81   - public void onPlayerStateChanged(int playerState) {
82   -
83   - }
84   -
85   - @Override
86   - public void setProgress(int duration, int position) {
87   -
88   - }
89   -
90   - @Override
91   - public void onLockStateChanged(boolean isLock) {
92   -
93   - }
94 87  
95 88 @Override
96 89 public boolean dispatchTouchEvent(MotionEvent ev) {
... ... @@ -113,4 +106,39 @@ public class DefaultErrorView extends LinearLayout implements IControlComponent
113 106 }
114 107 return super.dispatchTouchEvent(ev);
115 108 }
  109 +
  110 + @Override
  111 + public void onVisibilityChanged(boolean isVisible, Animation anim) {
  112 +
  113 + }
  114 +
  115 + @Override
  116 + public void onPlayerStateChanged(int playerState) {
  117 +
  118 + }
  119 +
  120 + @Override
  121 + public void setProgress(int duration, int position) {
  122 +
  123 + }
  124 +
  125 + @Override
  126 + public void onLockStateChanged(boolean isLock) {
  127 +
  128 + }
  129 +
  130 + @Override
  131 + public void onPlayError(PlayErrorException exception) {
  132 + //获取当前类型
  133 + if (null == tvMessage) {
  134 + return;
  135 + }
  136 + switch (exception.getErrorType()) {
  137 + case PlayErrorException.TYPE_NETWORK_ERROR:
  138 + tvMessage.setText(exception.getErrorMsg());
  139 + break;
  140 + }
  141 + }
  142 +
  143 +
116 144 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultPrepareView.java
... ... @@ -10,6 +10,7 @@ import android.widget.ImageView;
10 10 import android.widget.ProgressBar;
11 11  
12 12 import com.cnlive.cloud.video.R;
  13 +import com.libs.video.video.exoplayer.PlayErrorException;
13 14 import com.libs.video.video.exoplayer.controller.ControlWrapper;
14 15 import com.libs.video.video.exoplayer.controller.IControlComponent;
15 16 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -133,4 +134,9 @@ public class DefaultPrepareView extends FrameLayout implements IControlComponent
133 134 public void onLockStateChanged(boolean isLocked) {
134 135  
135 136 }
  137 +
  138 + @Override
  139 + public void onPlayError(PlayErrorException exception) {
  140 +
  141 + }
136 142 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultTitleView.java
... ... @@ -18,6 +18,7 @@ import android.widget.TextView;
18 18  
19 19  
20 20 import com.cnlive.cloud.video.R;
  21 +import com.libs.video.video.exoplayer.PlayErrorException;
21 22 import com.libs.video.video.exoplayer.controller.ControlWrapper;
22 23 import com.libs.video.video.exoplayer.controller.IControlComponent;
23 24 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -184,6 +185,11 @@ public class DefaultTitleView extends FrameLayout implements IControlComponent {
184 185 }
185 186 }
186 187  
  188 + @Override
  189 + public void onPlayError(PlayErrorException exception) {
  190 +
  191 + }
  192 +
187 193 private static class BatteryReceiver extends BroadcastReceiver {
188 194 private ImageView pow;
189 195  
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DefaultVodControlView.java
... ... @@ -18,6 +18,7 @@ import android.widget.SeekBar;
18 18 import android.widget.TextView;
19 19  
20 20 import com.cnlive.cloud.video.R;
  21 +import com.libs.video.video.exoplayer.PlayErrorException;
21 22 import com.libs.video.video.exoplayer.controller.ControlWrapper;
22 23 import com.libs.video.video.exoplayer.controller.IControlComponent;
23 24 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -234,6 +235,11 @@ public class DefaultVodControlView extends FrameLayout implements IControlCompon
234 235 }
235 236  
236 237 @Override
  238 + public void onPlayError(PlayErrorException exception) {
  239 +
  240 + }
  241 +
  242 + @Override
237 243 public void onClick(View v) {
238 244 int id = v.getId();
239 245 if (id == R.id.fullscreen) {
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/GestureView.java
... ... @@ -15,6 +15,7 @@ import android.widget.TextView;
15 15  
16 16  
17 17 import com.cnlive.cloud.video.R;
  18 +import com.libs.video.video.exoplayer.PlayErrorException;
18 19 import com.libs.video.video.exoplayer.controller.ControlWrapper;
19 20 import com.libs.video.video.exoplayer.controller.IGestureComponent;
20 21 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -158,4 +159,9 @@ public class GestureView extends FrameLayout implements IGestureComponent {
158 159  
159 160 }
160 161  
  162 + @Override
  163 + public void onPlayError(PlayErrorException exception) {
  164 +
  165 + }
  166 +
161 167 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/LiveControlView.java
... ... @@ -12,6 +12,7 @@ import android.widget.ImageView;
12 12 import android.widget.LinearLayout;
13 13  
14 14 import com.cnlive.cloud.video.R;
  15 +import com.libs.video.video.exoplayer.PlayErrorException;
15 16 import com.libs.video.video.exoplayer.controller.ControlWrapper;
16 17 import com.libs.video.video.exoplayer.controller.IControlComponent;
17 18 import com.libs.video.video.exoplayer.play.CNVideoView;
... ... @@ -145,6 +146,11 @@ public class LiveControlView extends FrameLayout implements IControlComponent, V
145 146 }
146 147  
147 148 @Override
  149 + public void onPlayError(PlayErrorException exception) {
  150 +
  151 + }
  152 +
  153 + @Override
148 154 public void onClick(View v) {
149 155 int id = v.getId();
150 156 if (id == R.id.fullscreen) {
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/BaseVideoController.java
... ... @@ -11,6 +11,8 @@ import android.view.animation.AlphaAnimation;
11 11 import android.view.animation.Animation;
12 12 import android.widget.FrameLayout;
13 13  
  14 +import com.libs.video.video.exoplayer.PlayErrorException;
  15 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
14 16 import com.libs.video.video.exoplayer.play.CNVideoView;
15 17 import com.libs.video.video.exoplayer.play.VideoViewManager;
16 18 import com.libs.video.video.exoplayer.util.CutoutUtil;
... ... @@ -108,8 +110,9 @@ public abstract class BaseVideoController extends FrameLayout
108 110 * 重要:此方法用于将{@link CNVideoView} 和控制器绑定
109 111 */
110 112 @CallSuper
111   - public void setMediaPlayer(MediaPlayerControl mediaPlayer) {
  113 + public void setMediaPlayer(MediaPlayerControl mediaPlayer,AbstractPlayer abstractPlayer) {
112 114 mControlWrapper = new ControlWrapper(mediaPlayer, this);
  115 + mControlWrapper.setAbstractPlayer(abstractPlayer);
113 116 //绑定ControlComponent和Controller
114 117 for (Map.Entry<IControlComponent, Boolean> next : mControlComponents.entrySet()) {
115 118 IControlComponent component = next.getKey();
... ... @@ -549,6 +552,15 @@ public abstract class BaseVideoController extends FrameLayout
549 552 onPlayStateChanged(playState);
550 553 }
551 554  
  555 + @CallSuper
  556 + public void onPlayError(PlayErrorException exception){
  557 + for (Map.Entry<IControlComponent, Boolean> next
  558 + : mControlComponents.entrySet()) {
  559 + IControlComponent component = next.getKey();
  560 + component.onPlayError(exception);
  561 + }
  562 + }
  563 +
552 564 /**
553 565 * 子类重写此方法并在其中更新控制器在不同播放状态下的ui
554 566 */
... ... @@ -645,5 +657,6 @@ public abstract class BaseVideoController extends FrameLayout
645 657  
646 658 }
647 659  
  660 +
648 661 //------------------------ end handle event change ------------------------//
649 662 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/ControlWrapper.java
... ... @@ -6,6 +6,8 @@ import android.graphics.Bitmap;
6 6  
7 7 import androidx.annotation.NonNull;
8 8  
  9 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
  10 +
9 11 /**
10 12 * 此类的目的是为了在ControlComponent中既能调用VideoView的api又能调用BaseVideoController的api,
11 13 * 并对部分api做了封装,方便使用
... ... @@ -14,12 +16,21 @@ public class ControlWrapper implements MediaPlayerControl, IVideoController {
14 16  
15 17 private MediaPlayerControl mPlayerControl;
16 18 private IVideoController mController;
  19 + private AbstractPlayer abstractPlayer;//用于获取当前的播放器
17 20  
18 21 public ControlWrapper(@NonNull MediaPlayerControl playerControl, @NonNull IVideoController controller) {
19 22 mPlayerControl = playerControl;
20 23 mController = controller;
21 24 }
22 25  
  26 + public void setAbstractPlayer(AbstractPlayer abstractPlayer) {
  27 + this.abstractPlayer = abstractPlayer;
  28 + }
  29 +
  30 + public AbstractPlayer getAbstractPlayer() {
  31 + return abstractPlayer;
  32 + }
  33 +
23 34 @Override
24 35 public int getMediaCount() {
25 36 return mPlayerControl.getMediaCount();
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/IControlComponent.java
... ... @@ -5,6 +5,8 @@ import android.view.animation.Animation;
5 5  
6 6 import androidx.annotation.NonNull;
7 7  
  8 +import com.libs.video.video.exoplayer.PlayErrorException;
  9 +
8 10 /**
9 11 * 视频控制组件接口
10 12 */
... ... @@ -41,6 +43,7 @@ public interface IControlComponent {
41 43 */
42 44 void onPlayerStateChanged(int playerState);
43 45  
  46 +
44 47 /**
45 48 * 设置进度
46 49 *
... ... @@ -56,4 +59,10 @@ public interface IControlComponent {
56 59 */
57 60 void onLockStateChanged(boolean isLocked);
58 61  
  62 + /**
  63 + * 播放出错
  64 + *
  65 + * @param exception
  66 + */
  67 + void onPlayError(PlayErrorException exception);
59 68 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/MediaPlayerControl.java
... ... @@ -2,10 +2,13 @@ package com.libs.video.video.exoplayer.controller;
2 2  
3 3 import android.graphics.Bitmap;
4 4  
  5 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
  6 +
5 7 /**
6 8 * 播放器控制接口
7 9 */
8 10 public interface MediaPlayerControl {
  11 +
9 12 int getMediaCount();
10 13  
11 14 void start();
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/StandardVideoController.java
... ... @@ -3,6 +3,7 @@ package com.libs.video.video.exoplayer.controller;
3 3 import android.content.Context;
4 4 import android.content.pm.ActivityInfo;
5 5 import android.util.AttributeSet;
  6 +import android.util.Log;
6 7 import android.view.View;
7 8 import android.view.ViewGroup;
8 9 import android.view.animation.Animation;
... ... @@ -12,6 +13,7 @@ import android.widget.ProgressBar;
12 13 import android.widget.Toast;
13 14  
14 15 import com.cnlive.cloud.video.R;
  16 +import com.libs.video.video.exoplayer.PlayErrorException;
15 17 import com.libs.video.video.exoplayer.component.DefaultCompleteView;
16 18 import com.libs.video.video.exoplayer.component.DefaultErrorView;
17 19 import com.libs.video.video.exoplayer.component.GestureView;
... ... @@ -19,6 +21,7 @@ import com.libs.video.video.exoplayer.component.LiveControlView;
19 21 import com.libs.video.video.exoplayer.component.DefaultPrepareView;
20 22 import com.libs.video.video.exoplayer.component.DefaultTitleView;
21 23 import com.libs.video.video.exoplayer.component.DefaultVodControlView;
  24 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
22 25 import com.libs.video.video.exoplayer.play.CNVideoView;
23 26 import com.libs.video.video.exoplayer.util.PlayerUtils;
24 27  
... ... @@ -30,7 +33,7 @@ import androidx.annotation.Nullable;
30 33 * 直播/点播控制器
31 34 */
32 35  
33   -public class StandardVideoController extends GestureVideoController implements View.OnClickListener {
  36 +public class StandardVideoController extends GestureVideoController implements View.OnClickListener, AbstractPlayer.PlayerEventListener {
34 37  
35 38 protected ImageView mLockButton;//锁屏按钮
36 39  
... ... @@ -61,6 +64,7 @@ public class StandardVideoController extends GestureVideoController implements V
61 64 mLoadingProgress = findViewById(R.id.loading);
62 65 }
63 66  
  67 +
64 68 /**
65 69 * 快速添加各个组件
66 70 *
... ... @@ -199,4 +203,29 @@ public class StandardVideoController extends GestureVideoController implements V
199 203 }
200 204 return super.onBackPressed();
201 205 }
  206 +
  207 + @Override
  208 + public void onError(PlayErrorException playErrorException) {
  209 + Log.e("测试", "onError: " );
  210 + }
  211 +
  212 + @Override
  213 + public void onCompletion() {
  214 +
  215 + }
  216 +
  217 + @Override
  218 + public void onInfo(int what, int extra) {
  219 +
  220 + }
  221 +
  222 + @Override
  223 + public void onPrepared() {
  224 +
  225 + }
  226 +
  227 + @Override
  228 + public void onVideoSizeChanged(int width, int height) {
  229 +
  230 + }
202 231 }
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/AbstractPlayer.java
... ... @@ -4,6 +4,8 @@ import android.content.res.AssetFileDescriptor;
4 4 import android.view.Surface;
5 5 import android.view.SurfaceHolder;
6 6  
  7 +import com.libs.video.video.exoplayer.PlayErrorException;
  8 +
7 9 import java.util.Map;
8 10  
9 11 /**
... ... @@ -155,7 +157,7 @@ public abstract class AbstractPlayer {
155 157  
156 158 public interface PlayerEventListener {
157 159  
158   - void onError();
  160 + void onError(PlayErrorException playErrorException);
159 161  
160 162 void onCompletion();
161 163  
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/AndroidMediaPlayer.java
... ... @@ -9,6 +9,9 @@ import android.os.Build;
9 9 import android.view.Surface;
10 10 import android.view.SurfaceHolder;
11 11  
  12 +import com.libs.video.video.exoplayer.PlayErrorException;
  13 +
  14 +import java.io.IOException;
12 15 import java.util.Map;
13 16  
14 17 public class AndroidMediaPlayer extends AbstractPlayer {
... ... @@ -40,7 +43,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
40 43 try {
41 44 mMediaPlayer.setDataSource(mAppContext, Uri.parse(path), headers);
42 45 } catch (Exception e) {
43   - mPlayerEventListener.onError();
  46 + getException(e);
44 47 }
45 48 }
46 49  
... ... @@ -49,16 +52,37 @@ public class AndroidMediaPlayer extends AbstractPlayer {
49 52 try {
50 53 mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
51 54 } catch (Exception e) {
52   - mPlayerEventListener.onError();
  55 + getException(e);
53 56 }
54 57 }
55 58  
  59 + /**
  60 + * 获取当前异常
  61 + *
  62 + * @param e
  63 + */
  64 + private void getException(Exception e) {
  65 + PlayErrorException errorException = null;
  66 + if (e instanceof IOException) {
  67 + errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IOException, e.getMessage());
  68 + } else if (e instanceof IllegalArgumentException) {
  69 + errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IllegalArgumentException, e.getMessage());
  70 + } else if (e instanceof SecurityException) {
  71 + errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_SecurityException, e.getMessage());
  72 + } else if (e instanceof IllegalStateException) {
  73 + errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IllegalStateException, e.getMessage());
  74 + } else {
  75 + errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_unknownException, e.getMessage());
  76 + }
  77 + mPlayerEventListener.onError(errorException);
  78 + }
  79 +
56 80 @Override
57 81 public void start() {
58 82 try {
59 83 mMediaPlayer.start();
60 84 } catch (IllegalStateException e) {
61   - mPlayerEventListener.onError();
  85 + getException(e);
62 86 }
63 87 }
64 88  
... ... @@ -67,7 +91,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
67 91 try {
68 92 mMediaPlayer.pause();
69 93 } catch (IllegalStateException e) {
70   - mPlayerEventListener.onError();
  94 + getException(e);
71 95 }
72 96 }
73 97  
... ... @@ -76,7 +100,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
76 100 try {
77 101 mMediaPlayer.stop();
78 102 } catch (IllegalStateException e) {
79   - mPlayerEventListener.onError();
  103 + getException(e);
80 104 }
81 105 }
82 106  
... ... @@ -86,7 +110,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
86 110 mIsPreparing = true;
87 111 mMediaPlayer.prepareAsync();
88 112 } catch (IllegalStateException e) {
89   - mPlayerEventListener.onError();
  113 + getException(e);
90 114 }
91 115 }
92 116  
... ... @@ -108,7 +132,8 @@ public class AndroidMediaPlayer extends AbstractPlayer {
108 132 try {
109 133 mMediaPlayer.seekTo((int) time);
110 134 } catch (IllegalStateException e) {
111   - mPlayerEventListener.onError();
  135 + mPlayerEventListener.onError(new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IllegalStateException, e.getMessage()));
  136 +
112 137 }
113 138 }
114 139  
... ... @@ -152,7 +177,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
152 177 try {
153 178 mMediaPlayer.setSurface(surface);
154 179 } catch (Exception e) {
155   - mPlayerEventListener.onError();
  180 + getException(e);
156 181 }
157 182 }
158 183  
... ... @@ -161,7 +186,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
161 186 try {
162 187 mMediaPlayer.setDisplay(holder);
163 188 } catch (Exception e) {
164   - mPlayerEventListener.onError();
  189 + getException(e);
165 190 }
166 191 }
167 192  
... ... @@ -186,7 +211,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
186 211 try {
187 212 mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(speed));
188 213 } catch (Exception e) {
189   - mPlayerEventListener.onError();
  214 + getException(e);
190 215 }
191 216 }
192 217 }
... ... @@ -200,7 +225,12 @@ public class AndroidMediaPlayer extends AbstractPlayer {
200 225 private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
201 226 @Override
202 227 public boolean onError(MediaPlayer mp, int what, int extra) {
203   - mPlayerEventListener.onError();
  228 + PlayErrorException errorException = new PlayErrorException();
  229 + errorException.setErrorType(PlayErrorException.TYPE_MediaPlayer_ON_ERROR);
  230 + errorException.setMediaPlayer(mp);
  231 + errorException.setMediaPlayer_what(what);
  232 + errorException.setMediaPlayer_extra(extra);
  233 + mPlayerEventListener.onError(errorException);
204 234 return true;
205 235 }
206 236 };
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/CNVideoView.java
... ... @@ -19,6 +19,7 @@ import android.view.WindowManager;
19 19 import android.widget.FrameLayout;
20 20  
21 21 import com.cnlive.cloud.video.R;
  22 +import com.libs.video.video.exoplayer.PlayErrorException;
22 23 import com.libs.video.video.exoplayer.controller.BaseVideoController;
23 24 import com.libs.video.video.exoplayer.controller.MediaPlayerControl;
24 25 import com.libs.video.video.exoplayer.util.L;
... ... @@ -157,6 +158,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
157 158 a.recycle();
158 159  
159 160 initView();
  161 +
160 162 }
161 163  
162 164 /**
... ... @@ -182,6 +184,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
182 184 }
183 185  
184 186  
  187 +
185 188 /**
186 189 * 当前媒体数量
187 190 *
... ... @@ -231,8 +234,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
231 234 if (mProgressManager != null) {
232 235 mCurrentPosition = mProgressManager.getSavedProgress(mUrl);
233 236 }
234   - //初始化播放器
235   - initPlayer();
  237 + initPlayer();
236 238 //添加渲染视图
237 239 addDisplay();
238 240 startPrepare(false);
... ... @@ -267,7 +269,10 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
267 269 * 初始化播放器
268 270 */
269 271 protected void initPlayer() {
270   - mMediaPlayer = mPlayerFactory.createPlayer(getContext());
  272 + if (null==mMediaPlayer){
  273 + //初始化播放器
  274 + mMediaPlayer = mPlayerFactory.createPlayer(getContext());
  275 + }
271 276 mMediaPlayer.setPlayerEventListener(this);
272 277 setInitOptions();
273 278 mMediaPlayer.initPlayer();
... ... @@ -553,8 +558,11 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
553 558 * 视频播放出错回调
554 559 */
555 560 @Override
556   - public void onError() {
  561 + public void onError(PlayErrorException playErrorException) {
557 562 mPlayerContainer.setKeepScreenOn(false);
  563 + if (mVideoController != null) {
  564 + mVideoController.onPlayError(playErrorException);
  565 + }
558 566 setPlayState(STATE_ERROR);
559 567 }
560 568  
... ... @@ -933,10 +941,14 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
933 941 * 设置控制器,传null表示移除控制器
934 942 */
935 943 public void setVideoController(@Nullable BaseVideoController mediaController) {
  944 + if (null==mMediaPlayer){
  945 + //初始化播放器
  946 + mMediaPlayer = mPlayerFactory.createPlayer(getContext());
  947 + }
936 948 mPlayerContainer.removeView(mVideoController);
937 949 mVideoController = mediaController;
938 950 if (mediaController != null) {
939   - mediaController.setMediaPlayer(this);
  951 + mediaController.setMediaPlayer(this,mMediaPlayer);
940 952 LayoutParams params = new LayoutParams(
941 953 ViewGroup.LayoutParams.MATCH_PARENT,
942 954 ViewGroup.LayoutParams.MATCH_PARENT);
... ...
cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/exoplayer/ExoMediaPlayer.java
... ... @@ -6,6 +6,8 @@ import android.os.Handler;
6 6 import android.view.Surface;
7 7 import android.view.SurfaceHolder;
8 8  
  9 +import com.cnlive.cloud.video.R;
  10 +import com.cnlive.core.libs.base.util.NetworkUtil;
9 11 import com.google.android.exoplayer2.DefaultLoadControl;
10 12 import com.google.android.exoplayer2.DefaultRenderersFactory;
11 13 import com.google.android.exoplayer2.ExoPlaybackException;
... ... @@ -26,6 +28,7 @@ import com.google.android.exoplayer2.util.Clock;
26 28 import com.google.android.exoplayer2.util.EventLogger;
27 29 import com.google.android.exoplayer2.util.Util;
28 30 import com.google.android.exoplayer2.video.VideoListener;
  31 +import com.libs.video.video.exoplayer.PlayErrorException;
29 32 import com.libs.video.video.exoplayer.play.AbstractPlayer;
30 33 import com.libs.video.video.exoplayer.play.VideoViewManager;
31 34  
... ... @@ -221,7 +224,9 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla
221 224 mSpeedPlaybackParameters = null;
222 225 }
223 226  
224   - /**获取当前的播放进度
  227 + /**
  228 + * 获取当前的播放进度
  229 + *
225 230 * @return
226 231 */
227 232 @Override
... ... @@ -371,12 +376,39 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla
371 376 */
372 377 @Override
373 378 public void onPlayerError(ExoPlaybackException error) {
374   - if (mPlayerEventListener != null) {
375   - mPlayerEventListener.onError();
  379 + if (mPlayerEventListener != null && null != mAppContext) {
  380 + PlayErrorException errorException = null;
  381 + switch (error.type) {
  382 + //资源异常
  383 + case ExoPlaybackException.TYPE_SOURCE:
  384 + //先判断是否有网络连接
  385 + if (!NetworkUtil.isConnectInternet(mAppContext)) {
  386 + errorException = new PlayErrorException(PlayErrorException.TYPE_NETWORK_ERROR, mAppContext.getResources().getString(R.string.cnvideo_no_network));
  387 + } else {
  388 + errorException = new PlayErrorException(PlayErrorException.TYPE_SOURCE_ERROR, mAppContext.getResources().getString(R.string.cnvideo_load_source_error));
  389 + }
  390 + break;
  391 + //内存溢出
  392 + case ExoPlaybackException.TYPE_OUT_OF_MEMORY:
  393 + errorException = new PlayErrorException(PlayErrorException.TYPE_OUT_OF_MEMORY, error.getMessage());
  394 + break;
  395 + case ExoPlaybackException.TYPE_UNEXPECTED:
  396 + errorException = new PlayErrorException(PlayErrorException.TYPE_UNEXPECTED_ERROR, error.getMessage());
  397 + break;
  398 +
  399 + case ExoPlaybackException.TYPE_RENDERER:
  400 + errorException = new PlayErrorException(PlayErrorException.TYPE_RENDERER_ERROR, error.getMessage());
  401 + break;
  402 + }
  403 + if (null != errorException) {
  404 + mPlayerEventListener.onError(errorException);
  405 + }
376 406 }
377 407 }
378 408  
379   - /**视频大小发生变化
  409 + /**
  410 + * 视频大小发生变化
  411 + *
380 412 * @param width
381 413 * @param height
382 414 * @param unappliedRotationDegrees
... ...
cloud/video/src/main/res/drawable/cnvideo_shape_status_view_btn.xml
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3   - <solid android:color="@color/cnvideo_theme_color"/>
  3 + <solid android:color="@color/cnvideo_color_btn_error"/>
4 4 <corners android:radius="30dp"/>
5 5 </shape>
6 6 \ No newline at end of file
... ...
cloud/video/src/main/res/layout/cnvideo_layout_error_view.xml
... ... @@ -11,17 +11,18 @@
11 11 android:orientation="vertical">
12 12  
13 13 <TextView
14   - android:id="@+id/message"
  14 + android:id="@+id/tv_message"
15 15 android:layout_width="wrap_content"
16 16 android:layout_height="wrap_content"
17 17 android:gravity="center"
18 18 android:text="@string/cnvideo_error_message"
19   - android:textColor="@android:color/white" />
  19 + android:textColor="@android:color/white"
  20 + android:textSize="16sp" />
20 21  
21   - <TextView
22   - android:id="@+id/status_btn"
  22 + <Button
  23 + android:id="@+id/btn_retry"
23 24 android:layout_width="wrap_content"
24   - android:layout_height="wrap_content"
  25 + android:layout_height="30dp"
25 26 android:layout_marginTop="16dp"
26 27 android:background="@drawable/cnvideo_shape_status_view_btn"
27 28 android:gravity="center"
... ... @@ -30,7 +31,8 @@
30 31 android:paddingRight="18dp"
31 32 android:paddingBottom="4dp"
32 33 android:text="@string/cnvideo_retry"
33   - android:textColor="@android:color/white" />
  34 + android:textColor="@android:color/white"
  35 + android:textSize="15sp" />
34 36  
35 37 </LinearLayout>
36 38 </FrameLayout>
37 39 \ No newline at end of file
... ...