diff --git a/app/src/main/java/com/github/tvbox/osc/player/controller/BoxVideoController.java b/app/src/main/java/com/github/tvbox/osc/player/controller/BoxVideoController.java index d4d6ed9d..91d3661b 100644 --- a/app/src/main/java/com/github/tvbox/osc/player/controller/BoxVideoController.java +++ b/app/src/main/java/com/github/tvbox/osc/player/controller/BoxVideoController.java @@ -214,21 +214,4 @@ public class BoxVideoController extends GestureVideoController implements View.O } simSeekPosition = position; } - - private OnScreenLongPressListener screenLongPressListener; - - public interface OnScreenLongPressListener { - void longPress(); - } - - public void setScreenLongPressListener(OnScreenLongPressListener screenLongPressListener) { - this.screenLongPressListener = screenLongPressListener; - } - - @Override - public void onLongPress(MotionEvent e) { - if (screenLongPressListener != null) - screenLongPressListener.longPress(); - super.onLongPress(e); - } } diff --git a/app/src/main/java/com/github/tvbox/osc/player/controller/LiveVideoController.java b/app/src/main/java/com/github/tvbox/osc/player/controller/LiveVideoController.java new file mode 100644 index 00000000..edfe83ff --- /dev/null +++ b/app/src/main/java/com/github/tvbox/osc/player/controller/LiveVideoController.java @@ -0,0 +1,155 @@ +package com.github.tvbox.osc.player.controller; + + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.animation.Animation; +import android.widget.ProgressBar; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.github.tvbox.osc.R; + +import java.util.Map; + +import xyz.doikki.videoplayer.controller.GestureVideoController; +import xyz.doikki.videoplayer.controller.IControlComponent; +import xyz.doikki.videoplayer.controller.IGestureComponent; +import xyz.doikki.videoplayer.player.VideoView; +import xyz.doikki.videoplayer.player.VideoViewManager; +import xyz.doikki.videoplayer.util.PlayerUtils; + +/** + * 直播/点播控制器 + * 注意:此控制器仅做一个参考,如果想定制ui,你可以直接继承GestureVideoController或者BaseVideoController实现 + * 你自己的控制器 + * Created by dueeeke on 2017/4/7. + */ + +public class LiveVideoController extends GestureVideoController implements View.OnClickListener { + + protected ProgressBar mLoadingProgress; + + public LiveVideoController(@NonNull Context context) { + this(context, null); + VideoViewManager.instance().setPlayOnMobileNetwork(true); + } + + public LiveVideoController(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public LiveVideoController(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected int getLayoutId() { + return R.layout.box_standard_controller; + } + + @Override + protected void initView() { + super.initView(); + mLoadingProgress = findViewById(R.id.loading); + } + + @Override + public void onClick(View v) { + int i = v.getId(); + } + + @Override + protected void onVisibilityChanged(boolean isVisible, Animation anim) { + if (mControlWrapper.isFullScreen()) { + if (isVisible) { + } else { + } + } + } + + private OnPlayStateChangedListener playStateChangedListener = null; + + public interface OnPlayStateChangedListener { + void playStateChanged(int playState); + } + + public void setPlayStateChangedListener(OnPlayStateChangedListener playStateChangedListener) { + this.playStateChangedListener = playStateChangedListener; + } + + @Override + protected void onPlayStateChanged(int playState) { + super.onPlayStateChanged(playState); + switch (playState) { + //调用release方法会回到此状态 + case VideoView.STATE_IDLE: + mLoadingProgress.setVisibility(GONE); + break; + case VideoView.STATE_PLAYING: + case VideoView.STATE_PAUSED: + case VideoView.STATE_PREPARED: + case VideoView.STATE_ERROR: + case VideoView.STATE_BUFFERED: + mLoadingProgress.setVisibility(GONE); + break; + case VideoView.STATE_PREPARING: + case VideoView.STATE_BUFFERING: + mLoadingProgress.setVisibility(VISIBLE); + break; + case VideoView.STATE_PLAYBACK_COMPLETED: + mLoadingProgress.setVisibility(GONE); + break; + } + if (playStateChangedListener != null) + playStateChangedListener.playStateChanged(playState); + } + + private OnScreenTapListener screenTapListener; + + public interface OnScreenTapListener { + void tap(); + } + + public void setScreenTapListener(OnScreenTapListener screenTapListener) { + this.screenTapListener = screenTapListener; + } + + @Override + public boolean onSingleTapConfirmed(MotionEvent e) { + if (screenTapListener != null) + screenTapListener.tap(); + return super.onSingleTapConfirmed(e); + } + + private OnScreenLongPressListener screenLongPressListener = null; + + public interface OnScreenLongPressListener { + void longPress(); + } + + public void setScreenLongPressListener(OnScreenLongPressListener screenLongPressListener) { + this.screenLongPressListener = screenLongPressListener; + } + + @Override + public void onLongPress(MotionEvent e) { + if (screenLongPressListener != null) + screenLongPressListener.longPress(); + super.onLongPress(e); + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + return super.onScroll(e1, e2, distanceX, distanceY); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + return super.onTouchEvent(event); + } +} diff --git a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java index 8d22c2e4..b503085e 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/activity/LivePlayActivity.java @@ -26,20 +26,17 @@ import com.github.tvbox.osc.bean.LiveChannelGroup; import com.github.tvbox.osc.bean.LiveChannelItem; import com.github.tvbox.osc.bean.LiveSettingGroup; import com.github.tvbox.osc.bean.LiveSettingItem; -import com.github.tvbox.osc.player.controller.BoxVideoController; +import com.github.tvbox.osc.player.controller.LiveVideoController; import com.github.tvbox.osc.ui.adapter.LiveChannelGroupAdapter; import com.github.tvbox.osc.ui.adapter.LiveChannelItemAdapter; import com.github.tvbox.osc.ui.adapter.LiveSettingGroupAdapter; import com.github.tvbox.osc.ui.adapter.LiveSettingItemAdapter; import com.github.tvbox.osc.ui.tv.widget.ViewObj; -import com.github.tvbox.osc.util.DefaultConfig; import com.github.tvbox.osc.util.FastClickCheckUtil; import com.github.tvbox.osc.util.HawkConfig; import com.github.tvbox.osc.util.PlayerHelper; import com.google.gson.Gson; import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.lzy.okgo.OkGo; import com.lzy.okgo.callback.AbsCallback; import com.lzy.okgo.model.Response; @@ -50,8 +47,10 @@ import com.owen.tvrecyclerview.widget.V7LinearLayoutManager; import org.json.JSONException; import org.json.JSONObject; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; import xyz.doikki.videocontroller.component.GestureView; @@ -65,6 +64,8 @@ import xyz.doikki.videoplayer.player.VideoView; public class LivePlayActivity extends BaseActivity { private VideoView mVideoView; private TextView tvChannelInfo; + private TextView tvTime; + private TextView tvNetSpeed; private LinearLayout tvLeftChannelListLayout; private TvRecyclerView mChannelGroupView; private TvRecyclerView mLiveChannelView; @@ -84,6 +85,7 @@ public class LivePlayActivity extends BaseActivity { private int selectedChannelGroupIndex = 0; private int currentChannelGroupIndex = 0; private int currentLiveChannelIndex = 0; + private int currentLiveChangeSourceTimes = 0; private LiveChannelItem currentLiveChannelItem = null; @Override @@ -104,6 +106,8 @@ public class LivePlayActivity extends BaseActivity { mSettingGroupView = findViewById(R.id.mSettingGroupView); mSettingItemView = findViewById(R.id.mSettingItemView); tvChannelInfo = findViewById(R.id.tvChannel); + tvTime = findViewById(R.id.tvTime); + tvNetSpeed = findViewById(R.id.tvNetSpeed); initVideoView(); initChannelGroupView(); @@ -112,6 +116,8 @@ public class LivePlayActivity extends BaseActivity { initSettingItemView(); initLiveChannelList(); initLiveSettingGroupList(); + showTime(); + showNetSpeed(); } @Override @@ -134,14 +140,20 @@ public class LivePlayActivity extends BaseActivity { if (event.getAction() == KeyEvent.ACTION_DOWN) { int keyCode = event.getKeyCode(); if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN && !isListOrSettingLayoutVisible()) { - playNext(); + if (Hawk.get(HawkConfig.LIVE_CHANNEL_REVERSE, false)) + playPrevious(); + else + playNext(); } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP && !isListOrSettingLayoutVisible()) { - playPrevious(); + if (Hawk.get(HawkConfig.LIVE_CHANNEL_REVERSE, false)) + playNext(); + else + playPrevious(); } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && !isListOrSettingLayoutVisible()) { - preSourceUrl(); + playPreSource(); } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && !isListOrSettingLayoutVisible()) { - nextSourceUrl(); - } else if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) && !isListOrSettingLayoutVisible()) { + playNextSource(); + } else if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) && !isListOrSettingLayoutVisible()) { showChannelList(); } else if (keyCode == KeyEvent.KEYCODE_MENU && tvRightSettingLayout.getVisibility() == View.INVISIBLE) { showSettingGroup(); @@ -266,26 +278,36 @@ public class LivePlayActivity extends BaseActivity { private void playNext() { currentLiveChannelIndex++; - if (currentLiveChannelIndex >= liveChannelGroupList.get(currentChannelGroupIndex).getLiveChannels().size()) + if (currentLiveChannelIndex >= liveChannelGroupList.get(currentChannelGroupIndex).getLiveChannels().size()) { currentLiveChannelIndex = 0; - liveChannelItemAdapter.setSelectedChannelIndex(currentLiveChannelIndex); + if (Hawk.get(HawkConfig.LIVE_CROSS_GROUP, false)) { + currentChannelGroupIndex++; + if (currentChannelGroupIndex >= liveChannelGroupList.size()) + currentChannelGroupIndex = 0; + } + } playChannel(false); } private void playPrevious() { currentLiveChannelIndex--; - if (currentLiveChannelIndex < 0) + if (currentLiveChannelIndex < 0) { + if (Hawk.get(HawkConfig.LIVE_CROSS_GROUP, false)) { + currentChannelGroupIndex--; + if (currentChannelGroupIndex < 0) + currentChannelGroupIndex = liveChannelGroupList.size() - 1; + } currentLiveChannelIndex = liveChannelGroupList.get(currentChannelGroupIndex).getLiveChannels().size() - 1; - liveChannelItemAdapter.setSelectedChannelIndex(currentLiveChannelIndex); + } playChannel(false); } - public void preSourceUrl() { + public void playPreSource() { currentLiveChannelItem.preSource(); playChannel(true); } - public void nextSourceUrl() { + public void playNextSource() { currentLiveChannelItem.nextSource(); playChannel(true); } @@ -358,19 +380,41 @@ public class LivePlayActivity extends BaseActivity { }; private void initVideoView() { - BoxVideoController controller = new BoxVideoController(this); - controller.setScreenTapListener(new BoxVideoController.OnScreenTapListener() { + LiveVideoController controller = new LiveVideoController(this); + controller.setScreenTapListener(new LiveVideoController.OnScreenTapListener() { @Override public void tap() { showChannelList(); } }); - controller.setScreenLongPressListener(new BoxVideoController.OnScreenLongPressListener() { + controller.setScreenLongPressListener(new LiveVideoController.OnScreenLongPressListener() { @Override public void longPress() { showSettingGroup(); } }); + controller.setPlayStateChangedListener(new LiveVideoController.OnPlayStateChangedListener() { + @Override + public void playStateChanged(int playState) { + switch (playState) { + case VideoView.STATE_IDLE: + case VideoView.STATE_PLAYING: + case VideoView.STATE_PAUSED: + case VideoView.STATE_PREPARED: + case VideoView.STATE_ERROR: + case VideoView.STATE_BUFFERED: + case VideoView.STATE_PLAYBACK_COMPLETED: + currentLiveChangeSourceTimes = 0; + mHandler.removeCallbacks(mConnectTimeoutChangeSourceRun); + break; + case VideoView.STATE_PREPARING: + case VideoView.STATE_BUFFERING: + currentLiveChangeSourceTimes++; + mHandler.postDelayed(mConnectTimeoutChangeSourceRun, (Hawk.get(HawkConfig.LIVE_CONNECT_TIMEOUT, 1) + 1) * 5000); + break; + } + } + }); controller.addControlComponent(new GestureView(this)); controller.setCanChangePosition(false); controller.setEnableInNormal(true); @@ -379,6 +423,20 @@ public class LivePlayActivity extends BaseActivity { mVideoView.setProgressManager(null); } + private Runnable mConnectTimeoutChangeSourceRun = new Runnable() { + @Override + public void run() { + if (currentLiveChannelItem.getSourceNum() == currentLiveChangeSourceTimes) { + if (Hawk.get(HawkConfig.LIVE_CHANNEL_REVERSE, false)) + playPrevious(); + else + playNext(); + } else { + playNextSource(); + } + } + }; + private void initChannelGroupView() { mChannelGroupView.setHasFixedSize(true); mChannelGroupView.setLayoutManager(new V7LinearLayoutManager(this.mContext, 1, false)); @@ -635,20 +693,28 @@ public class LivePlayActivity extends BaseActivity { Hawk.put(HawkConfig.LIVE_CONNECT_TIMEOUT, position); break; case 4://超时换源 + boolean select = false; switch (position) { case 0: - Hawk.put(HawkConfig.LIVE_SHOW_TIME, false); + select = !Hawk.get(HawkConfig.LIVE_SHOW_TIME, false); + Hawk.put(HawkConfig.LIVE_SHOW_TIME, select); + showTime(); break; case 1: - Hawk.put(HawkConfig.LIVE_SHOW_NET_SPEED, false); + select = !Hawk.get(HawkConfig.LIVE_SHOW_NET_SPEED, false); + Hawk.put(HawkConfig.LIVE_SHOW_NET_SPEED, select); + showNetSpeed(); break; case 2: - Hawk.put(HawkConfig.LIVE_CHANNEL_REVERSE, false); + select = !Hawk.get(HawkConfig.LIVE_CHANNEL_REVERSE, false); + Hawk.put(HawkConfig.LIVE_CHANNEL_REVERSE, select); break; case 3: - Hawk.put(HawkConfig.LIVE_CROSS_GROUP, false); + select = !Hawk.get(HawkConfig.LIVE_CROSS_GROUP, false); + Hawk.put(HawkConfig.LIVE_CROSS_GROUP, select); break; } + liveSettingItemAdapter.selectItem(position, select, false); break; } mHandler.removeCallbacks(mHideSettingLayoutRun); @@ -826,4 +892,42 @@ public class LivePlayActivity extends BaseActivity { } } } + + void showTime() { + if (Hawk.get(HawkConfig.LIVE_SHOW_TIME, false)) { + mHandler.post(mUpdateTimeRun); + tvTime.setVisibility(View.VISIBLE); + } else { + mHandler.removeCallbacks(mUpdateTimeRun); + tvTime.setVisibility(View.GONE); + } + } + + private Runnable mUpdateTimeRun = new Runnable() { + @Override + public void run() { + Date day=new Date(); + SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"); + tvTime.setText(df.format(day)); + mHandler.postDelayed(this, 1000); + } + }; + + private void showNetSpeed() { + if (Hawk.get(HawkConfig.LIVE_SHOW_NET_SPEED, false)) { + mHandler.post(mUpdateNetSpeedRun); + tvNetSpeed.setVisibility(View.VISIBLE); + } else { + mHandler.removeCallbacks(mUpdateNetSpeedRun); + tvNetSpeed.setVisibility(View.GONE); + } + } + + private Runnable mUpdateNetSpeedRun = new Runnable() { + @Override + public void run() { + tvNetSpeed.setText(String.format("%.2fMB/s", (float)mVideoView.getTcpSpeed() / 1024.0 / 1024.0)); + mHandler.postDelayed(this, 1000); + } + }; } \ No newline at end of file diff --git a/app/src/main/java/com/github/tvbox/osc/ui/adapter/LiveSettingItemAdapter.java b/app/src/main/java/com/github/tvbox/osc/ui/adapter/LiveSettingItemAdapter.java index d7818e3e..8801c0d1 100644 --- a/app/src/main/java/com/github/tvbox/osc/ui/adapter/LiveSettingItemAdapter.java +++ b/app/src/main/java/com/github/tvbox/osc/ui/adapter/LiveSettingItemAdapter.java @@ -56,8 +56,6 @@ public class LiveSettingItemAdapter extends BaseQuickAdapter + + + \ No newline at end of file