Commit beebfcb82e1bb56f88280aef9c2e4578bf37aae3

Authored by YangShuai
1 parent 4c81413f

修改视频加载失败提示页

cloud/video/build.gradle
@@ -15,4 +15,5 @@ dependencies { @@ -15,4 +15,5 @@ dependencies {
15 implementation project(path: ':core:network') 15 implementation project(path: ':core:network')
16 api 'com.google.android.exoplayer:exoplayer:2.11.0' 16 api 'com.google.android.exoplayer:exoplayer:2.11.0'
17 api 'com.google.android.exoplayer:extension-rtmp:2.11.0' 17 api 'com.google.android.exoplayer:extension-rtmp:2.11.0'
  18 + api 'com.google.android.exoplayer:extension-ima:2.11.0'
18 } 19 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/CNLiveBaseVideoControlView.java
@@ -190,7 +190,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements @@ -190,7 +190,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements
190 if (context instanceof Activity) { 190 if (context instanceof Activity) {
191 this.activity = (Activity) context; 191 this.activity = (Activity) context;
192 } 192 }
193 -  
194 formatBuilder = new StringBuilder(); 193 formatBuilder = new StringBuilder();
195 formatter = new Formatter(formatBuilder, Locale.getDefault()); 194 formatter = new Formatter(formatBuilder, Locale.getDefault());
196 period = new Timeline.Period(); 195 period = new Timeline.Period();
@@ -213,10 +212,11 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements @@ -213,10 +212,11 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements
213 public void run() { 212 public void run() {
214 //初始化视图UI 213 //初始化视图UI
215 initView(); 214 initView();
  215 + //初始化竖屏UI
216 if (null != componentListener && null != basePortraitView) { 216 if (null != componentListener && null != basePortraitView) {
217 initPortraitView(basePortraitView, componentListener); 217 initPortraitView(basePortraitView, componentListener);
218 } 218 }
219 - 219 + //点击监听器
220 baseRootView.setOnClickListener(new OnClickListener() { 220 baseRootView.setOnClickListener(new OnClickListener() {
221 @Override 221 @Override
222 public void onClick(View v) { 222 public void onClick(View v) {
@@ -226,24 +226,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements @@ -226,24 +226,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements
226 } 226 }
227 227
228 }); 228 });
229 -// post(new Runnable() {  
230 -// @Override  
231 -// public void run() {  
232 -// initView();  
233 -// if (null != componentListener && null != basePortraitView) {  
234 -// initPortraitView(basePortraitView, componentListener);  
235 -// }  
236 -// LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);  
237 -// LinearLayout lineLayout = new LinearLayout(context);  
238 -// lineLayout.setOrientation(LinearLayout.VERTICAL);  
239 -// lineLayout.setLayoutParams(params);  
240 -// lineLayout.setGravity(Gravity.CENTER );  
241 -// lineLayout.setClickable(true);  
242 -// lineLayout.setBackgroundColor(ContextCompat.getColor(context,R.color.black));  
243 -//  
244 -// addView(lineLayout);  
245 -// }  
246 -// });  
247 } 229 }
248 230
249 /** 231 /**
@@ -693,7 +675,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements @@ -693,7 +675,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements
693 if (player != null) { 675 if (player != null) {
694 position = player.getContentPosition(); 676 position = player.getContentPosition();
695 } 677 }
696 - Log.e(TAG, "updateProgress: " + position);  
697 //先移除之前的动作 678 //先移除之前的动作
698 removeCallbacks(updateProgressAction); 679 removeCallbacks(updateProgressAction);
699 int playbackState = player == null ? Player.STATE_IDLE : player.getPlaybackState(); 680 int playbackState = player == null ? Player.STATE_IDLE : player.getPlaybackState();
cloud/video/src/main/java/com/libs/video/video/exoplayer/CNLiveVideoView.java
@@ -25,6 +25,7 @@ import android.view.TextureView; @@ -25,6 +25,7 @@ import android.view.TextureView;
25 import android.view.View; 25 import android.view.View;
26 import android.view.ViewGroup; 26 import android.view.ViewGroup;
27 import android.view.WindowManager; 27 import android.view.WindowManager;
  28 +import android.widget.Button;
28 import android.widget.FrameLayout; 29 import android.widget.FrameLayout;
29 import android.widget.ImageView; 30 import android.widget.ImageView;
30 import android.widget.LinearLayout; 31 import android.widget.LinearLayout;
@@ -37,6 +38,7 @@ import androidx.annotation.Nullable; @@ -37,6 +38,7 @@ import androidx.annotation.Nullable;
37 import androidx.core.content.ContextCompat; 38 import androidx.core.content.ContextCompat;
38 39
39 import com.cnlive.cloud.video.R; 40 import com.cnlive.cloud.video.R;
  41 +import com.cnlive.core.libs.base.util.NetworkUtil;
40 import com.google.android.exoplayer2.C; 42 import com.google.android.exoplayer2.C;
41 import com.google.android.exoplayer2.ControlDispatcher; 43 import com.google.android.exoplayer2.ControlDispatcher;
42 import com.google.android.exoplayer2.DefaultControlDispatcher; 44 import com.google.android.exoplayer2.DefaultControlDispatcher;
@@ -66,6 +68,8 @@ import com.google.android.exoplayer2.util.Util; @@ -66,6 +68,8 @@ import com.google.android.exoplayer2.util.Util;
66 import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView; 68 import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView;
67 import com.google.android.exoplayer2.video.VideoListener; 69 import com.google.android.exoplayer2.video.VideoListener;
68 70
  71 +import org.w3c.dom.Text;
  72 +
69 import java.io.IOException; 73 import java.io.IOException;
70 import java.lang.annotation.Documented; 74 import java.lang.annotation.Documented;
71 import java.lang.annotation.Retention; 75 import java.lang.annotation.Retention;
@@ -126,7 +130,11 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -126,7 +130,11 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
126 @Nullable 130 @Nullable
127 private final View bufferingView; 131 private final View bufferingView;
128 @Nullable 132 @Nullable
129 - private final LinearLayout errorMessageView; 133 + private final LinearLayout errorMessageView;//播放错误页
  134 + @Nullable
  135 + private final Button btnRetry;//重试按钮
  136 + @Nullable
  137 + private final TextView tvErrorMsg;//错误信息
130 @Nullable 138 @Nullable
131 private CNLiveBaseVideoControlView controller; 139 private CNLiveBaseVideoControlView controller;
132 @Nullable 140 @Nullable
@@ -164,6 +172,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -164,6 +172,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
164 componentListener = new CNLiveVideoView.ComponentListener(); 172 componentListener = new CNLiveVideoView.ComponentListener();
165 if (context instanceof Activity) { 173 if (context instanceof Activity) {
166 this.activity = (Activity) context; 174 this.activity = (Activity) context;
  175 + this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
167 } 176 }
168 } 177 }
169 178
@@ -172,6 +181,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -172,6 +181,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
172 componentListener = new CNLiveVideoView.ComponentListener(); 181 componentListener = new CNLiveVideoView.ComponentListener();
173 if (context instanceof Activity) { 182 if (context instanceof Activity) {
174 this.activity = (Activity) context; 183 this.activity = (Activity) context;
  184 + this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
175 } 185 }
176 } 186 }
177 187
@@ -180,8 +190,9 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -180,8 +190,9 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
180 super(context, attrs, defStyleAttr); 190 super(context, attrs, defStyleAttr);
181 if (context instanceof Activity) { 191 if (context instanceof Activity) {
182 this.activity = (Activity) context; 192 this.activity = (Activity) context;
183 - } 193 + this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
184 194
  195 + }
185 componentListener = new CNLiveVideoView.ComponentListener(); 196 componentListener = new CNLiveVideoView.ComponentListener();
186 //初始化videoplayer 197 //初始化videoplayer
187 player = new VideoPlayer(context); 198 player = new VideoPlayer(context);
@@ -195,6 +206,8 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -195,6 +206,8 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
195 subtitleView = null; 206 subtitleView = null;
196 bufferingView = null; 207 bufferingView = null;
197 errorMessageView = null; 208 errorMessageView = null;
  209 + btnRetry = null;
  210 + tvErrorMsg = null;
198 controller = null; 211 controller = null;
199 adOverlayFrameLayout = null; 212 adOverlayFrameLayout = null;
200 overlayFrameLayout = null; 213 overlayFrameLayout = null;
@@ -220,7 +233,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -220,7 +233,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
220 boolean controllerHideOnTouch = true; 233 boolean controllerHideOnTouch = true;
221 boolean controllerAutoShow = true; 234 boolean controllerAutoShow = true;
222 boolean controllerHideDuringAds = true; 235 boolean controllerHideDuringAds = true;
223 - int showBuffering = SHOW_BUFFERING_NEVER; 236 + int showBuffering = SHOW_BUFFERING_WHEN_PLAYING;
224 if (attrs != null) { 237 if (attrs != null) {
225 TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PlayerView, 0, 0); 238 TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PlayerView, 0, 0);
226 try { 239 try {
@@ -320,12 +333,18 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -320,12 +333,18 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
320 333
321 // Error message view. 334 // Error message view.
322 errorMessageView = findViewById(R.id.cnlive_error_message); 335 errorMessageView = findViewById(R.id.cnlive_error_message);
  336 + tvErrorMsg = findViewById(R.id.tv_error_msg);
323 if (errorMessageView != null) { 337 if (errorMessageView != null) {
324 errorMessageView.setVisibility(View.GONE); 338 errorMessageView.setVisibility(View.GONE);
325 } 339 }
326 - errorMessageView.setOnClickListener(new OnClickListener() { 340 + btnRetry = findViewById(R.id.btn_retry);
  341 + btnRetry.setOnClickListener(new OnClickListener() {
327 @Override 342 @Override
328 public void onClick(View view) { 343 public void onClick(View view) {
  344 + if (!NetworkUtil.isConnectInternet(getContext())) {
  345 + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_no_network));
  346 + return;
  347 + }
329 errorMessageView.setVisibility(GONE); 348 errorMessageView.setVisibility(GONE);
330 player.retry(); 349 player.retry();
331 } 350 }
@@ -416,10 +435,10 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -416,10 +435,10 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
416 } 435 }
417 Uri mp4VideoUri = Uri.parse("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8"); 436 Uri mp4VideoUri = Uri.parse("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");
418 List<String> list = new ArrayList<>(); 437 List<String> list = new ArrayList<>();
419 - list.add("https://qq.com-ok-qq.com/20191005/24249_f5e36323/index.m3u8");  
420 - list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");  
421 - list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");  
422 - 438 + list.add("http://sbslive.cnrmobile.com/storage/storage4/76/23/10/14de52115893fb5371b7e064f910ab7b.3gp");
  439 +// list.add("https://qq.com-ok-qq.com/20191005/24249_f5e36323/index.m3u8");
  440 +// list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");
  441 +// list.add("http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8");
423 442
424 player.setDataSource(list); 443 player.setDataSource(list);
425 player.prepare(); 444 player.prepare();
@@ -513,7 +532,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -513,7 +532,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
513 if (subtitleView != null) { 532 if (subtitleView != null) {
514 subtitleView.setCues(null); 533 subtitleView.setCues(null);
515 } 534 }
516 - updateBuffering(); 535 +// updateBuffering();
517 updateErrorMessage(); 536 updateErrorMessage();
518 updateForCurrentTrackSelections(/* isNewPlayer= */ true); 537 updateForCurrentTrackSelections(/* isNewPlayer= */ true);
519 if (player != null) { 538 if (player != null) {
@@ -691,8 +710,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -691,8 +710,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
691 } 710 }
692 711
693 /** 712 /**
694 - * Sets whether a buffering spinner is displayed when the player is in the buffering state. The  
695 - * buffering spinner is not displayed by default. 713 + * 是否显示加载loading
696 * 714 *
697 * @param showBuffering Whether the buffering icon is displayed 715 * @param showBuffering Whether the buffering icon is displayed
698 * @deprecated Use {@link #setShowBuffering(int)} 716 * @deprecated Use {@link #setShowBuffering(int)}
@@ -1436,16 +1454,6 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -1436,16 +1454,6 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
1436 1454
1437 // Player.EventListener implementation 1455 // Player.EventListener implementation
1438 1456
1439 - @Override  
1440 - public void onPlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {  
1441 - updateBuffering();  
1442 - updateErrorMessage();  
1443 - if (isPlayingAd() && controllerHideDuringAds) {  
1444 - hideController();  
1445 - } else {  
1446 -// maybeShowController(false);  
1447 - }  
1448 - }  
1449 1457
1450 @Override 1458 @Override
1451 public void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) { 1459 public void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) {
@@ -1524,33 +1532,6 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -1524,33 +1532,6 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
1524 } 1532 }
1525 } 1533 }
1526 1534
1527 - @Override  
1528 - public void onLoadingChanged(EventTime eventTime, boolean isLoading) {  
1529 - if (null == bufferingView) {  
1530 - return;  
1531 - }  
1532 -// if (isLoading) {  
1533 -// bufferingView.setVisibility(VISIBLE);  
1534 -// } else {  
1535 -// bufferingView.setVisibility(GONE);  
1536 -// }  
1537 - Log.e(TAG, "onLoadingChanged: ");  
1538 - }  
1539 -  
1540 - @Override  
1541 - public void onLoadCanceled(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) {  
1542 - if (null == bufferingView) {  
1543 - return;  
1544 - }  
1545 - bufferingView.setVisibility(GONE);  
1546 - Log.e(TAG, "onLoadCanceled: ");  
1547 - }  
1548 -  
1549 - @Override  
1550 - public void onLoadStarted(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) {  
1551 - Log.e(TAG, "onLoadStarted: ");  
1552 - bufferingView.setVisibility(VISIBLE);  
1553 - }  
1554 1535
1555 @Override 1536 @Override
1556 public void onPlayerError(EventTime eventTime, ExoPlaybackException error) { 1537 public void onPlayerError(EventTime eventTime, ExoPlaybackException error) {
@@ -1561,44 +1542,60 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv @@ -1561,44 +1542,60 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv
1561 switch (error.type) { 1542 switch (error.type) {
1562 case ExoPlaybackException.TYPE_SOURCE: 1543 case ExoPlaybackException.TYPE_SOURCE:
1563 // 加载资源时出错 1544 // 加载资源时出错
  1545 + //判断当前是否有网络
  1546 + if (!NetworkUtil.isConnectInternet(getContext())) {
  1547 + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_no_network));
  1548 + } else {
  1549 + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_load_source_error));
  1550 + }
1564 break; 1551 break;
1565 case ExoPlaybackException.TYPE_RENDERER: 1552 case ExoPlaybackException.TYPE_RENDERER:
1566 // 渲染时出错 1553 // 渲染时出错
  1554 + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_renderer_source_error));
1567 break; 1555 break;
1568 case ExoPlaybackException.TYPE_UNEXPECTED: 1556 case ExoPlaybackException.TYPE_UNEXPECTED:
1569 // 意外的错误 1557 // 意外的错误
  1558 + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_unexpected_error));
1570 break; 1559 break;
1571 } 1560 }
1572 } 1561 }
1573 1562
1574 @Override 1563 @Override
1575 public void onLoadCompleted(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) { 1564 public void onLoadCompleted(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) {
1576 - bufferingView.setVisibility(GONE); 1565 +
1577 } 1566 }
1578 1567
1579 @Override 1568 @Override
1580 public void onLoadError(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData, IOException error, boolean wasCanceled) { 1569 public void onLoadError(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData, IOException error, boolean wasCanceled) {
1581 - bufferingView.setVisibility(GONE);  
1582 } 1570 }
1583 1571
1584 @Override 1572 @Override
1585 public void onPlayerStateChanged(EventTime eventTime, boolean playWhenReady, int playbackState) { 1573 public void onPlayerStateChanged(EventTime eventTime, boolean playWhenReady, int playbackState) {
  1574 + updateBuffering();
  1575 + updateErrorMessage();
  1576 + if (isPlayingAd() && controllerHideDuringAds) {
  1577 + hideController();
  1578 + } else {
  1579 +// maybeShowController(false);
  1580 + }
1586 switch (playbackState) { 1581 switch (playbackState) {
1587 case Player.STATE_IDLE: 1582 case Player.STATE_IDLE:
1588 - Log.e(TAG, "空闲 "); 1583 + Log.e(TAG, "onPlayerStateChanged空闲 ");
1589 // 空闲 1584 // 空闲
1590 break; 1585 break;
1591 case Player.STATE_BUFFERING: 1586 case Player.STATE_BUFFERING:
1592 // 缓冲中 1587 // 缓冲中
1593 - Log.e(TAG, "缓冲中 "); 1588 + Log.e(TAG, "onPlayerStateChanged缓冲中 ");
  1589 + bufferingView.setVisibility(VISIBLE);
1594 break; 1590 break;
1595 case Player.STATE_READY: 1591 case Player.STATE_READY:
1596 - Log.e(TAG, "准备好 ");  
1597 - 1592 + Log.e(TAG, "onPlayerStateChanged准备好 " + playWhenReady);
  1593 +// bufferingView.setVisibility(GONE);
1598 // 准备好 1594 // 准备好
1599 break; 1595 break;
1600 case Player.STATE_ENDED: 1596 case Player.STATE_ENDED:
1601 // 结束 1597 // 结束
  1598 + Log.e(TAG, "onPlayerStateChanged结束 " + playWhenReady);
1602 break; 1599 break;
1603 default: 1600 default:
1604 break; 1601 break;
cloud/video/src/main/java/com/libs/video/video/exoplayer/MyTestControlView.java
@@ -87,14 +87,21 @@ public class MyTestControlView extends CNLiveBaseVideoControlView { @@ -87,14 +87,21 @@ public class MyTestControlView extends CNLiveBaseVideoControlView {
87 } else if (view.getId() == R.id.iv_play) { 87 } else if (view.getId() == R.id.iv_play) {
88 if (isPlaying()) { 88 if (isPlaying()) {
89 pauseVideo(); 89 pauseVideo();
90 - ivPortraitPlay.setBackground(ContextCompat.getDrawable(context, R.drawable.icon_cnvideo_play_pause_icon)); 90 + ivPortraitPlay.setImageResource(R.drawable.icon_cnvideo_play_def_icon);
91 } else { 91 } else {
92 playVideo(); 92 playVideo();
93 - ivPortraitPlay.setBackground(ContextCompat.getDrawable(context, R.drawable.icon_cnvideo_play_def_icon)); 93 + ivPortraitPlay.setImageResource(R.drawable.icon_cnvideo_play_pause_icon);
94 } 94 }
95 } 95 }
96 } 96 }
97 97
  98 + @Override
  99 + public void onPlayerStateChanged(EventTime eventTime, boolean playWhenReady, int playbackState) {
  100 + super.onPlayerStateChanged(eventTime, playWhenReady, playbackState);
  101 +// if (playWhenReady) {
  102 +// ivPortraitPlay.setImageResource(ContextCompat.getDrawable(context, R.drawable.icon_cnvideo_play_pause_icon));
  103 +// }
  104 + }
98 105
99 @Override 106 @Override
100 public void onProgressChange(long position, String durationStr) { 107 public void onProgressChange(long position, String durationStr) {
cloud/video/src/main/java/com/libs/video/video/exoplayer/VideoPlayer.java
@@ -14,12 +14,17 @@ import com.google.android.exoplayer2.Player; @@ -14,12 +14,17 @@ import com.google.android.exoplayer2.Player;
14 import com.google.android.exoplayer2.SimpleExoPlayer; 14 import com.google.android.exoplayer2.SimpleExoPlayer;
15 import com.google.android.exoplayer2.Timeline; 15 import com.google.android.exoplayer2.Timeline;
16 import com.google.android.exoplayer2.analytics.AnalyticsListener; 16 import com.google.android.exoplayer2.analytics.AnalyticsListener;
  17 +import com.google.android.exoplayer2.ext.ima.ImaAdsLoader;
17 import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory; 18 import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory;
  19 +import com.google.android.exoplayer2.metadata.Metadata;
  20 +import com.google.android.exoplayer2.metadata.MetadataOutput;
18 import com.google.android.exoplayer2.source.ConcatenatingMediaSource; 21 import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
19 import com.google.android.exoplayer2.source.ExtractorMediaSource; 22 import com.google.android.exoplayer2.source.ExtractorMediaSource;
20 import com.google.android.exoplayer2.source.MediaSource; 23 import com.google.android.exoplayer2.source.MediaSource;
21 import com.google.android.exoplayer2.source.ProgressiveMediaSource; 24 import com.google.android.exoplayer2.source.ProgressiveMediaSource;
22 import com.google.android.exoplayer2.source.TrackGroupArray; 25 import com.google.android.exoplayer2.source.TrackGroupArray;
  26 +import com.google.android.exoplayer2.source.ads.AdsLoader;
  27 +import com.google.android.exoplayer2.source.ads.AdsMediaSource;
23 import com.google.android.exoplayer2.source.dash.DashMediaSource; 28 import com.google.android.exoplayer2.source.dash.DashMediaSource;
24 import com.google.android.exoplayer2.source.hls.HlsMediaSource; 29 import com.google.android.exoplayer2.source.hls.HlsMediaSource;
25 import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; 30 import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
@@ -29,6 +34,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray; @@ -29,6 +34,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
29 import com.google.android.exoplayer2.ui.PlayerView; 34 import com.google.android.exoplayer2.ui.PlayerView;
30 import com.google.android.exoplayer2.upstream.DataSource; 35 import com.google.android.exoplayer2.upstream.DataSource;
31 import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; 36 import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
  37 +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
32 import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; 38 import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
33 import com.google.android.exoplayer2.util.Util; 39 import com.google.android.exoplayer2.util.Util;
34 import com.google.android.exoplayer2.video.VideoDecoderOutputBuffer; 40 import com.google.android.exoplayer2.video.VideoDecoderOutputBuffer;
@@ -54,7 +60,7 @@ import javax.crypto.BadPaddingException; @@ -54,7 +60,7 @@ import javax.crypto.BadPaddingException;
54 import javax.crypto.IllegalBlockSizeException; 60 import javax.crypto.IllegalBlockSizeException;
55 import javax.crypto.NoSuchPaddingException; 61 import javax.crypto.NoSuchPaddingException;
56 62
57 -public class VideoPlayer implements IVideoPlayer { 63 +public class VideoPlayer implements IVideoPlayer, AnalyticsListener {
58 private static final String TAG = VideoPlayer.class.getName(); 64 private static final String TAG = VideoPlayer.class.getName();
59 public SimpleExoPlayer player;//exo播放器 65 public SimpleExoPlayer player;//exo播放器
60 // private Player.EventListener eventListener;//播放器监听器 66 // private Player.EventListener eventListener;//播放器监听器
@@ -91,6 +97,7 @@ public class VideoPlayer implements IVideoPlayer { @@ -91,6 +97,7 @@ public class VideoPlayer implements IVideoPlayer {
91 //初始化exoplayer 97 //初始化exoplayer
92 //step2. 创建播放器 98 //step2. 创建播放器
93 player = new SimpleExoPlayer.Builder(context).build(); 99 player = new SimpleExoPlayer.Builder(context).build();
  100 + player.addAnalyticsListener(this);
94 mContext = context; 101 mContext = context;
95 bandwidthMeter = DefaultBandwidthMeter.getSingletonInstance(context); 102 bandwidthMeter = DefaultBandwidthMeter.getSingletonInstance(context);
96 //创建资源工厂 103 //创建资源工厂
@@ -98,91 +105,11 @@ public class VideoPlayer implements IVideoPlayer { @@ -98,91 +105,11 @@ public class VideoPlayer implements IVideoPlayer {
98 httpDataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "app-name")); 105 httpDataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "app-name"));
99 //数据加载 106 //数据加载
100 mDataLoader = new DataLoader(); 107 mDataLoader = new DataLoader();
101 - //添加行为监听器  
102 - player.addListener(new Player.EventListener() {  
103 - @Override  
104 - public void onTimelineChanged(Timeline timeline, int reason) {  
105 -  
106 - }  
107 -  
108 - @Override  
109 - public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {  
110 -  
111 - }  
112 -  
113 - @Override  
114 - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {  
115 -  
116 - }  
117 -  
118 - @Override  
119 - public void onLoadingChanged(boolean isLoading) {  
120 -  
121 - }  
122 -  
123 - @Override  
124 - public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {  
125 -//状态改变监听  
126 - switch (playbackState) {  
127 - //这是初始状态,播放机停止时的状态,以及播放失败时的状态。  
128 - case Player.STATE_IDLE:  
129 - Log.d(TAG, "onPlayerStateChanged: STATE_IDLE");  
130 - break;  
131 - // 播放器无法立即从其当前位置进行播放。这主要是因为需要加载更多的数据。  
132 - case Player.STATE_BUFFERING:  
133 - Log.d(TAG, "onPlayerStateChanged: STATE_BUFFERING");  
134 - break;  
135 - //播放器可以立即从其当前位置进行播放。  
136 - case Player.STATE_READY:  
137 - Log.d(TAG, "onPlayerStateChanged: STATE_READY");  
138 - break;  
139 - //播放器完成了所有媒体的播放。  
140 - case Player.STATE_ENDED:  
141 - Log.d(TAG, "onPlayerStateChanged: STATE_ENDED");  
142 - break;  
143 - }  
144 - }  
145 -  
146 - @Override  
147 - public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) {  
148 -  
149 - }  
150 -  
151 - @Override  
152 - public void onIsPlayingChanged(boolean isPlaying) {  
153 -  
154 - }  
155 -  
156 - @Override  
157 - public void onRepeatModeChanged(int repeatMode) {  
158 -  
159 - }  
160 -  
161 - @Override  
162 - public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {  
163 -  
164 - }  
165 -  
166 - @Override  
167 - public void onPlayerError(ExoPlaybackException error) {  
168 -  
169 - }  
170 -  
171 - @Override  
172 - public void onPositionDiscontinuity(int reason) {  
173 -  
174 - }  
175 -  
176 - @Override  
177 - public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {  
178 -  
179 - }  
180 -  
181 - @Override  
182 - public void onSeekProcessed() { 108 + }
183 109
184 - }  
185 - }); 110 + @Override
  111 + public void onPlaybackParametersChanged(EventTime eventTime, PlaybackParameters playbackParameters) {
  112 + Log.e(TAG, "onPlaybackParametersChanged: " );
186 } 113 }
187 114
188 /** 115 /**
@@ -409,7 +336,6 @@ public class VideoPlayer implements IVideoPlayer { @@ -409,7 +336,6 @@ public class VideoPlayer implements IVideoPlayer {
409 } 336 }
410 } 337 }
411 338
412 -  
413 private MediaSource getPlayerMediaSource(String playerUrl) { 339 private MediaSource getPlayerMediaSource(String playerUrl) {
414 if (TextUtils.isEmpty(playerUrl)) { 340 if (TextUtils.isEmpty(playerUrl)) {
415 return null; 341 return null;
@@ -495,6 +421,7 @@ public class VideoPlayer implements IVideoPlayer { @@ -495,6 +421,7 @@ public class VideoPlayer implements IVideoPlayer {
495 return player.getCurrentTimeline(); 421 return player.getCurrentTimeline();
496 } 422 }
497 423
  424 +
498 @Override 425 @Override
499 public boolean isPlayingAd() { 426 public boolean isPlayingAd() {
500 return player.isPlayingAd(); 427 return player.isPlayingAd();
@@ -562,7 +489,6 @@ public class VideoPlayer implements IVideoPlayer { @@ -562,7 +489,6 @@ public class VideoPlayer implements IVideoPlayer {
562 489
563 @Override 490 @Override
564 public void release() { 491 public void release() {
565 -  
566 //释放资源 492 //释放资源
567 if (null != player) { 493 if (null != player) {
568 player.release(); 494 player.release();
@@ -641,4 +567,7 @@ public class VideoPlayer implements IVideoPlayer { @@ -641,4 +567,7 @@ public class VideoPlayer implements IVideoPlayer {
641 return player.getPlaybackError(); 567 return player.getPlaybackError();
642 } 568 }
643 569
  570 + @Override
  571 + public void onMetadata(EventTime eventTime, Metadata metadata) {
  572 + }
644 } 573 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/model/AdVideoModel.java 0 → 100644
  1 +package com.libs.video.video.exoplayer.model;
  2 +
  3 +/**
  4 + * 广告视频
  5 + */
  6 +public class AdVideoModel {
  7 + private String playerUrl;
  8 + private int videoType;
  9 +
  10 + public String getPlayerUrl() {
  11 + return playerUrl;
  12 + }
  13 +
  14 + public void setPlayerUrl(String playerUrl) {
  15 + this.playerUrl = playerUrl;
  16 + }
  17 +
  18 + public int getVideoType() {
  19 + return videoType;
  20 + }
  21 +
  22 + public void setVideoType(int videoType) {
  23 + this.videoType = videoType;
  24 + }
  25 +}
cloud/video/src/main/res/drawable/cnvideo_shape_error_btn_bg.xml 0 → 100644
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <corners android:radius="20dp" />
  4 + <solid android:color="@color/cnvideo_color_btn_error" />
  5 +</shape>
0 \ No newline at end of file 6 \ No newline at end of file
cloud/video/src/main/res/layout/layout_base_video_view.xml
@@ -59,9 +59,24 @@ @@ -59,9 +59,24 @@
59 android:gravity="center" 59 android:gravity="center"
60 android:orientation="vertical"> 60 android:orientation="vertical">
61 61
62 - <Button 62 + <TextView
  63 + android:id="@+id/tv_error_msg"
63 android:layout_width="wrap_content" 64 android:layout_width="wrap_content"
64 android:layout_height="wrap_content" 65 android:layout_height="wrap_content"
65 - android:text="刷新" /> 66 + android:layout_marginBottom="20dp"
  67 + android:text="@string/cnvideo_no_network"
  68 + android:textColor="@color/white"
  69 + android:textSize="16dp"
  70 + android:textStyle="bold" />
  71 +
  72 + <Button
  73 + android:id="@+id/btn_retry"
  74 + android:layout_width="wrap_content"
  75 + android:layout_height="35dp"
  76 + android:background="@drawable/cnvideo_shape_error_btn_bg"
  77 + android:text="点击重试"
  78 + android:textColor="@color/white"
  79 + android:textSize="15dp"
  80 + android:textStyle="bold" />
66 </LinearLayout> 81 </LinearLayout>
67 </merge> 82 </merge>
68 \ No newline at end of file 83 \ No newline at end of file
cloud/video/src/main/res/layout/layout_protrait_control_view.xml
@@ -22,12 +22,11 @@ @@ -22,12 +22,11 @@
22 22
23 <ImageView 23 <ImageView
24 android:id="@+id/iv_play" 24 android:id="@+id/iv_play"
25 - android:layout_width="20dp"  
26 - android:layout_height="20dp"  
27 - android:layout_marginLeft="10dp"  
28 - android:layout_marginRight="10dp"  
29 - android:background="@drawable/icon_cnvideo_play_pause_icon"  
30 - android:clickable="true" /> 25 + android:layout_width="40dp"
  26 + android:layout_height="40dp"
  27 + android:clickable="true"
  28 + android:padding="10dp"
  29 + android:src="@drawable/icon_cnvideo_play_def_icon" />
31 30
32 <TextView 31 <TextView
33 android:id="@+id/tv_current_time" 32 android:id="@+id/tv_current_time"
@@ -56,11 +55,10 @@ @@ -56,11 +55,10 @@
56 55
57 <ImageView 56 <ImageView
58 android:id="@+id/btn_start" 57 android:id="@+id/btn_start"
59 - android:layout_width="20dp"  
60 - android:layout_height="20dp"  
61 - android:layout_marginLeft="10dp"  
62 - android:layout_marginRight="10dp"  
63 - android:background="@drawable/bg_cnvideo_bottom_fullscreen_btn" /> 58 + android:layout_width="40dp"
  59 + android:layout_height="40dp"
  60 + android:padding="10dp"
  61 + android:src="@drawable/bg_cnvideo_bottom_fullscreen_btn" />
64 62
65 </LinearLayout> 63 </LinearLayout>
66 64
cloud/video/src/main/res/values/colors.xml 0 → 100644
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <color name="cnvideo_color_btn_error">#505050</color>
  4 +
  5 +</resources>
0 \ No newline at end of file 6 \ No newline at end of file
cloud/video/src/main/res/values/string_cnvideo_tip.xml 0 → 100644
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <string name="cnvideo_no_network">网络未连接,请检查网络后重试</string>
  4 + <string name="cnvideo_load_source_error">视频加载失败,请稍后重试</string>
  5 + <string name="cnvideo_renderer_source_error">视频渲染失败,请稍后重试</string>
  6 + <string name="cnvideo_unexpected_error">未知错误,请稍后重试</string>
  7 +
  8 +</resources>
0 \ No newline at end of file 9 \ No newline at end of file