Commit beebfcb82e1bb56f88280aef9c2e4578bf37aae3
1 parent
4c81413f
修改视频加载失败提示页
Showing
11 changed files
with
148 additions
and
177 deletions
cloud/video/build.gradle
cloud/video/src/main/java/com/libs/video/video/exoplayer/CNLiveBaseVideoControlView.java
| ... | ... | @@ -190,7 +190,6 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements |
| 190 | 190 | if (context instanceof Activity) { |
| 191 | 191 | this.activity = (Activity) context; |
| 192 | 192 | } |
| 193 | - | |
| 194 | 193 | formatBuilder = new StringBuilder(); |
| 195 | 194 | formatter = new Formatter(formatBuilder, Locale.getDefault()); |
| 196 | 195 | period = new Timeline.Period(); |
| ... | ... | @@ -213,10 +212,11 @@ public abstract class CNLiveBaseVideoControlView extends FrameLayout implements |
| 213 | 212 | public void run() { |
| 214 | 213 | //初始化视图UI |
| 215 | 214 | initView(); |
| 215 | + //初始化竖屏UI | |
| 216 | 216 | if (null != componentListener && null != basePortraitView) { |
| 217 | 217 | initPortraitView(basePortraitView, componentListener); |
| 218 | 218 | } |
| 219 | - | |
| 219 | + //点击监听器 | |
| 220 | 220 | baseRootView.setOnClickListener(new OnClickListener() { |
| 221 | 221 | @Override |
| 222 | 222 | public void onClick(View v) { |
| ... | ... | @@ -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 | 675 | if (player != null) { |
| 694 | 676 | position = player.getContentPosition(); |
| 695 | 677 | } |
| 696 | - Log.e(TAG, "updateProgress: " + position); | |
| 697 | 678 | //先移除之前的动作 |
| 698 | 679 | removeCallbacks(updateProgressAction); |
| 699 | 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 | 25 | import android.view.View; |
| 26 | 26 | import android.view.ViewGroup; |
| 27 | 27 | import android.view.WindowManager; |
| 28 | +import android.widget.Button; | |
| 28 | 29 | import android.widget.FrameLayout; |
| 29 | 30 | import android.widget.ImageView; |
| 30 | 31 | import android.widget.LinearLayout; |
| ... | ... | @@ -37,6 +38,7 @@ import androidx.annotation.Nullable; |
| 37 | 38 | import androidx.core.content.ContextCompat; |
| 38 | 39 | |
| 39 | 40 | import com.cnlive.cloud.video.R; |
| 41 | +import com.cnlive.core.libs.base.util.NetworkUtil; | |
| 40 | 42 | import com.google.android.exoplayer2.C; |
| 41 | 43 | import com.google.android.exoplayer2.ControlDispatcher; |
| 42 | 44 | import com.google.android.exoplayer2.DefaultControlDispatcher; |
| ... | ... | @@ -66,6 +68,8 @@ import com.google.android.exoplayer2.util.Util; |
| 66 | 68 | import com.google.android.exoplayer2.video.VideoDecoderGLSurfaceView; |
| 67 | 69 | import com.google.android.exoplayer2.video.VideoListener; |
| 68 | 70 | |
| 71 | +import org.w3c.dom.Text; | |
| 72 | + | |
| 69 | 73 | import java.io.IOException; |
| 70 | 74 | import java.lang.annotation.Documented; |
| 71 | 75 | import java.lang.annotation.Retention; |
| ... | ... | @@ -126,7 +130,11 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 126 | 130 | @Nullable |
| 127 | 131 | private final View bufferingView; |
| 128 | 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 | 138 | @Nullable |
| 131 | 139 | private CNLiveBaseVideoControlView controller; |
| 132 | 140 | @Nullable |
| ... | ... | @@ -164,6 +172,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 164 | 172 | componentListener = new CNLiveVideoView.ComponentListener(); |
| 165 | 173 | if (context instanceof Activity) { |
| 166 | 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 | 181 | componentListener = new CNLiveVideoView.ComponentListener(); |
| 173 | 182 | if (context instanceof Activity) { |
| 174 | 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 | 190 | super(context, attrs, defStyleAttr); |
| 181 | 191 | if (context instanceof Activity) { |
| 182 | 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 | 196 | componentListener = new CNLiveVideoView.ComponentListener(); |
| 186 | 197 | //初始化videoplayer |
| 187 | 198 | player = new VideoPlayer(context); |
| ... | ... | @@ -195,6 +206,8 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 195 | 206 | subtitleView = null; |
| 196 | 207 | bufferingView = null; |
| 197 | 208 | errorMessageView = null; |
| 209 | + btnRetry = null; | |
| 210 | + tvErrorMsg = null; | |
| 198 | 211 | controller = null; |
| 199 | 212 | adOverlayFrameLayout = null; |
| 200 | 213 | overlayFrameLayout = null; |
| ... | ... | @@ -220,7 +233,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 220 | 233 | boolean controllerHideOnTouch = true; |
| 221 | 234 | boolean controllerAutoShow = true; |
| 222 | 235 | boolean controllerHideDuringAds = true; |
| 223 | - int showBuffering = SHOW_BUFFERING_NEVER; | |
| 236 | + int showBuffering = SHOW_BUFFERING_WHEN_PLAYING; | |
| 224 | 237 | if (attrs != null) { |
| 225 | 238 | TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PlayerView, 0, 0); |
| 226 | 239 | try { |
| ... | ... | @@ -320,12 +333,18 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 320 | 333 | |
| 321 | 334 | // Error message view. |
| 322 | 335 | errorMessageView = findViewById(R.id.cnlive_error_message); |
| 336 | + tvErrorMsg = findViewById(R.id.tv_error_msg); | |
| 323 | 337 | if (errorMessageView != null) { |
| 324 | 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 | 342 | @Override |
| 328 | 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 | 348 | errorMessageView.setVisibility(GONE); |
| 330 | 349 | player.retry(); |
| 331 | 350 | } |
| ... | ... | @@ -416,10 +435,10 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 416 | 435 | } |
| 417 | 436 | Uri mp4VideoUri = Uri.parse("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8"); |
| 418 | 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 | 443 | player.setDataSource(list); |
| 425 | 444 | player.prepare(); |
| ... | ... | @@ -513,7 +532,7 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 513 | 532 | if (subtitleView != null) { |
| 514 | 533 | subtitleView.setCues(null); |
| 515 | 534 | } |
| 516 | - updateBuffering(); | |
| 535 | +// updateBuffering(); | |
| 517 | 536 | updateErrorMessage(); |
| 518 | 537 | updateForCurrentTrackSelections(/* isNewPlayer= */ true); |
| 519 | 538 | if (player != null) { |
| ... | ... | @@ -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 | 715 | * @param showBuffering Whether the buffering icon is displayed |
| 698 | 716 | * @deprecated Use {@link #setShowBuffering(int)} |
| ... | ... | @@ -1436,16 +1454,6 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 1436 | 1454 | |
| 1437 | 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 | 1458 | @Override |
| 1451 | 1459 | public void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) { |
| ... | ... | @@ -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 | 1536 | @Override |
| 1556 | 1537 | public void onPlayerError(EventTime eventTime, ExoPlaybackException error) { |
| ... | ... | @@ -1561,44 +1542,60 @@ public class CNLiveVideoView extends FrameLayout implements AdsLoader.AdViewProv |
| 1561 | 1542 | switch (error.type) { |
| 1562 | 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 | 1551 | break; |
| 1565 | 1552 | case ExoPlaybackException.TYPE_RENDERER: |
| 1566 | 1553 | // 渲染时出错 |
| 1554 | + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_renderer_source_error)); | |
| 1567 | 1555 | break; |
| 1568 | 1556 | case ExoPlaybackException.TYPE_UNEXPECTED: |
| 1569 | 1557 | // 意外的错误 |
| 1558 | + tvErrorMsg.setText(getContext().getString(R.string.cnvideo_unexpected_error)); | |
| 1570 | 1559 | break; |
| 1571 | 1560 | } |
| 1572 | 1561 | } |
| 1573 | 1562 | |
| 1574 | 1563 | @Override |
| 1575 | 1564 | public void onLoadCompleted(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) { |
| 1576 | - bufferingView.setVisibility(GONE); | |
| 1565 | + | |
| 1577 | 1566 | } |
| 1578 | 1567 | |
| 1579 | 1568 | @Override |
| 1580 | 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 | 1572 | @Override |
| 1585 | 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 | 1581 | switch (playbackState) { |
| 1587 | 1582 | case Player.STATE_IDLE: |
| 1588 | - Log.e(TAG, "空闲 "); | |
| 1583 | + Log.e(TAG, "onPlayerStateChanged空闲 "); | |
| 1589 | 1584 | // 空闲 |
| 1590 | 1585 | break; |
| 1591 | 1586 | case Player.STATE_BUFFERING: |
| 1592 | 1587 | // 缓冲中 |
| 1593 | - Log.e(TAG, "缓冲中 "); | |
| 1588 | + Log.e(TAG, "onPlayerStateChanged缓冲中 "); | |
| 1589 | + bufferingView.setVisibility(VISIBLE); | |
| 1594 | 1590 | break; |
| 1595 | 1591 | case Player.STATE_READY: |
| 1596 | - Log.e(TAG, "准备好 "); | |
| 1597 | - | |
| 1592 | + Log.e(TAG, "onPlayerStateChanged准备好 " + playWhenReady); | |
| 1593 | +// bufferingView.setVisibility(GONE); | |
| 1598 | 1594 | // 准备好 |
| 1599 | 1595 | break; |
| 1600 | 1596 | case Player.STATE_ENDED: |
| 1601 | 1597 | // 结束 |
| 1598 | + Log.e(TAG, "onPlayerStateChanged结束 " + playWhenReady); | |
| 1602 | 1599 | break; |
| 1603 | 1600 | default: |
| 1604 | 1601 | break; | ... | ... |
cloud/video/src/main/java/com/libs/video/video/exoplayer/MyTestControlView.java
| ... | ... | @@ -87,14 +87,21 @@ public class MyTestControlView extends CNLiveBaseVideoControlView { |
| 87 | 87 | } else if (view.getId() == R.id.iv_play) { |
| 88 | 88 | if (isPlaying()) { |
| 89 | 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 | 91 | } else { |
| 92 | 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 | 106 | @Override |
| 100 | 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 | 14 | import com.google.android.exoplayer2.SimpleExoPlayer; |
| 15 | 15 | import com.google.android.exoplayer2.Timeline; |
| 16 | 16 | import com.google.android.exoplayer2.analytics.AnalyticsListener; |
| 17 | +import com.google.android.exoplayer2.ext.ima.ImaAdsLoader; | |
| 17 | 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 | 21 | import com.google.android.exoplayer2.source.ConcatenatingMediaSource; |
| 19 | 22 | import com.google.android.exoplayer2.source.ExtractorMediaSource; |
| 20 | 23 | import com.google.android.exoplayer2.source.MediaSource; |
| 21 | 24 | import com.google.android.exoplayer2.source.ProgressiveMediaSource; |
| 22 | 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 | 28 | import com.google.android.exoplayer2.source.dash.DashMediaSource; |
| 24 | 29 | import com.google.android.exoplayer2.source.hls.HlsMediaSource; |
| 25 | 30 | import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; |
| ... | ... | @@ -29,6 +34,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray; |
| 29 | 34 | import com.google.android.exoplayer2.ui.PlayerView; |
| 30 | 35 | import com.google.android.exoplayer2.upstream.DataSource; |
| 31 | 36 | import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; |
| 37 | +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; | |
| 32 | 38 | import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; |
| 33 | 39 | import com.google.android.exoplayer2.util.Util; |
| 34 | 40 | import com.google.android.exoplayer2.video.VideoDecoderOutputBuffer; |
| ... | ... | @@ -54,7 +60,7 @@ import javax.crypto.BadPaddingException; |
| 54 | 60 | import javax.crypto.IllegalBlockSizeException; |
| 55 | 61 | import javax.crypto.NoSuchPaddingException; |
| 56 | 62 | |
| 57 | -public class VideoPlayer implements IVideoPlayer { | |
| 63 | +public class VideoPlayer implements IVideoPlayer, AnalyticsListener { | |
| 58 | 64 | private static final String TAG = VideoPlayer.class.getName(); |
| 59 | 65 | public SimpleExoPlayer player;//exo播放器 |
| 60 | 66 | // private Player.EventListener eventListener;//播放器监听器 |
| ... | ... | @@ -91,6 +97,7 @@ public class VideoPlayer implements IVideoPlayer { |
| 91 | 97 | //初始化exoplayer |
| 92 | 98 | //step2. 创建播放器 |
| 93 | 99 | player = new SimpleExoPlayer.Builder(context).build(); |
| 100 | + player.addAnalyticsListener(this); | |
| 94 | 101 | mContext = context; |
| 95 | 102 | bandwidthMeter = DefaultBandwidthMeter.getSingletonInstance(context); |
| 96 | 103 | //创建资源工厂 |
| ... | ... | @@ -98,91 +105,11 @@ public class VideoPlayer implements IVideoPlayer { |
| 98 | 105 | httpDataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "app-name")); |
| 99 | 106 | //数据加载 |
| 100 | 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 | 336 | } |
| 410 | 337 | } |
| 411 | 338 | |
| 412 | - | |
| 413 | 339 | private MediaSource getPlayerMediaSource(String playerUrl) { |
| 414 | 340 | if (TextUtils.isEmpty(playerUrl)) { |
| 415 | 341 | return null; |
| ... | ... | @@ -495,6 +421,7 @@ public class VideoPlayer implements IVideoPlayer { |
| 495 | 421 | return player.getCurrentTimeline(); |
| 496 | 422 | } |
| 497 | 423 | |
| 424 | + | |
| 498 | 425 | @Override |
| 499 | 426 | public boolean isPlayingAd() { |
| 500 | 427 | return player.isPlayingAd(); |
| ... | ... | @@ -562,7 +489,6 @@ public class VideoPlayer implements IVideoPlayer { |
| 562 | 489 | |
| 563 | 490 | @Override |
| 564 | 491 | public void release() { |
| 565 | - | |
| 566 | 492 | //释放资源 |
| 567 | 493 | if (null != player) { |
| 568 | 494 | player.release(); |
| ... | ... | @@ -641,4 +567,7 @@ public class VideoPlayer implements IVideoPlayer { |
| 641 | 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
cloud/video/src/main/res/layout/layout_base_video_view.xml
| ... | ... | @@ -59,9 +59,24 @@ |
| 59 | 59 | android:gravity="center" |
| 60 | 60 | android:orientation="vertical"> |
| 61 | 61 | |
| 62 | - <Button | |
| 62 | + <TextView | |
| 63 | + android:id="@+id/tv_error_msg" | |
| 63 | 64 | android:layout_width="wrap_content" |
| 64 | 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 | 81 | </LinearLayout> |
| 67 | 82 | </merge> |
| 68 | 83 | \ No newline at end of file | ... | ... |
cloud/video/src/main/res/layout/layout_protrait_control_view.xml
| ... | ... | @@ -22,12 +22,11 @@ |
| 22 | 22 | |
| 23 | 23 | <ImageView |
| 24 | 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 | 31 | <TextView |
| 33 | 32 | android:id="@+id/tv_current_time" |
| ... | ... | @@ -56,11 +55,10 @@ |
| 56 | 55 | |
| 57 | 56 | <ImageView |
| 58 | 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 | 63 | </LinearLayout> |
| 66 | 64 | ... | ... |
cloud/video/src/main/res/values/colors.xml
0 → 100644
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 | 9 | \ No newline at end of file | ... | ... |