diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 99ef2bf2..00000000
Binary files a/.DS_Store and /dev/null differ
diff --git a/.gitignore b/.gitignore
index 81d4b505..ed7ba8ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,5 @@ captures/
# Keystore files
*.jks
+.DS_Store
+*/.DS_Store
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 13ed4651..f15f0386 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -76,6 +76,8 @@
android:name=".ui.TestPlayActivity"
android:exported="true"/>
+
\ No newline at end of file
diff --git a/app/src/main/java/com/kk/taurus/avplayer/HomeActivity.java b/app/src/main/java/com/kk/taurus/avplayer/HomeActivity.java
index 139cd0f3..acbda3f6 100644
--- a/app/src/main/java/com/kk/taurus/avplayer/HomeActivity.java
+++ b/app/src/main/java/com/kk/taurus/avplayer/HomeActivity.java
@@ -13,6 +13,7 @@
import com.kk.taurus.avplayer.ui.InputUrlPlayActivity;
import com.kk.taurus.avplayer.ui.MultiPlayActivity;
+import com.kk.taurus.avplayer.ui.TvBaseVideoViewActivity;
import com.kk.taurus.avplayer.ui.ViewPagerPlayActivity;
import com.kk.taurus.avplayer.ui.listplay.MultiListActivity;
import com.kk.taurus.avplayer.ui.ShareAnimationActivityA;
@@ -96,6 +97,10 @@ public void multiVideoPlay(View view){
intentTo(MultiPlayActivity.class);
}
+ public void tvPlayUserBaseVideoView(View view){
+ intentTo(TvBaseVideoViewActivity.class);
+ }
+
public void viewPagerPlay(View view){
intentTo(ViewPagerPlayActivity.class);
}
diff --git a/app/src/main/java/com/kk/taurus/avplayer/cover/BaseKeyEventCover.java b/app/src/main/java/com/kk/taurus/avplayer/cover/BaseKeyEventCover.java
new file mode 100644
index 00000000..ce33c027
--- /dev/null
+++ b/app/src/main/java/com/kk/taurus/avplayer/cover/BaseKeyEventCover.java
@@ -0,0 +1,100 @@
+package com.kk.taurus.avplayer.cover;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.KeyEvent;
+
+import com.kk.taurus.playerbase.event.OnPlayerEventListener;
+import com.kk.taurus.playerbase.player.IPlayer;
+import com.kk.taurus.playerbase.receiver.BaseCover;
+import com.kk.taurus.playerbase.touch.OnKeyEventListener;
+
+public abstract class BaseKeyEventCover extends BaseCover implements OnKeyEventListener {
+ public BaseKeyEventCover(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onPlayerEvent(int eventCode, Bundle bundle) {
+ switch (eventCode) {
+ case OnPlayerEventListener.PLAYER_EVENT_ON_PREPARED:
+
+ break;
+ }
+ }
+
+ @Override
+ public void onKeyDownInCover(int keyCode, KeyEvent event) {
+ dispatchKeyEventInner(true, event);
+ }
+
+ @Override
+ public void onKeyUpInCover(int keyCode, KeyEvent event) {
+ dispatchKeyEventInner(false, event);
+ }
+
+ private void dispatchKeyEventInner(boolean down, KeyEvent event){
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ onBackKeyEvent(down, event);
+ }
+ if (!isActiveState()) {
+ return;
+ }
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_MENU:
+ onMenuKeyEvent(down, event);
+ break;
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ case KeyEvent.KEYCODE_ENTER:
+ onCenterKeyEvent(down, event);
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ onUpKeyEvent(down, event);
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ onDownKeyEvent(down, event);
+ break;
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ onLeftKeyEvent(down, event);
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ onRightKeyEvent(down, event);
+ break;
+ default:
+ break;
+ }
+ }
+
+ protected void onCenterKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected void onUpKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected void onDownKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected void onLeftKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected void onRightKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected void onBackKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected void onMenuKeyEvent(boolean down, KeyEvent event){
+
+ }
+
+ protected boolean isActiveState(){
+ int state = getPlayerStateGetter().getState();
+ return state >= IPlayer.STATE_PREPARED && state <= IPlayer.STATE_PAUSED;
+ }
+}
diff --git a/app/src/main/java/com/kk/taurus/avplayer/cover/TvControllerCover.java b/app/src/main/java/com/kk/taurus/avplayer/cover/TvControllerCover.java
new file mode 100644
index 00000000..b86cab4d
--- /dev/null
+++ b/app/src/main/java/com/kk/taurus/avplayer/cover/TvControllerCover.java
@@ -0,0 +1,258 @@
+package com.kk.taurus.avplayer.cover;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.kk.taurus.avplayer.R;
+import com.kk.taurus.avplayer.play.DataInter;
+import com.kk.taurus.playerbase.entity.DataSource;
+import com.kk.taurus.playerbase.event.BundlePool;
+import com.kk.taurus.playerbase.event.EventKey;
+import com.kk.taurus.playerbase.event.OnPlayerEventListener;
+import com.kk.taurus.playerbase.player.IPlayer;
+import com.kk.taurus.playerbase.player.OnTimerUpdateListener;
+import com.kk.taurus.playerbase.utils.TimeUtil;
+
+public class TvControllerCover extends BaseKeyEventCover implements OnTimerUpdateListener {
+ private static final String TAG = "TvControllerCover";
+ private TextView mTopTitle, mCurrTime, mTotalTime;
+ private ImageView mStateIcon;
+ private SeekBar mSeekBar, mBottomSeekBar;
+ private View mBottomContainer;
+
+ private int mBufferPercentage;
+
+ private int mSeekProgress = -1;
+ private String mTimeFormat;
+
+ private boolean mTimerUpdateProgressEnable = false;
+
+ private Handler mHandler = new Handler();
+ public TvControllerCover(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected View onCreateCoverView(Context context) {
+ View view = View.inflate(context, R.layout.layout_controller_cover, null);
+ mTopTitle = view.findViewById(R.id.cover_player_controller_text_view_video_title);
+ mStateIcon = view.findViewById(R.id.cover_player_controller_image_view_play_state);
+ mCurrTime = view.findViewById(R.id.cover_player_controller_text_view_curr_time);
+ mTotalTime = view.findViewById(R.id.cover_player_controller_text_view_total_time);
+ mSeekBar = view.findViewById(R.id.cover_player_controller_seek_bar);
+ mBottomSeekBar = view.findViewById(R.id.cover_bottom_seek_bar);
+ mBottomContainer = view.findViewById(R.id.cover_player_controller_bottom_container);
+ view.findViewById(R.id.cover_player_controller_image_view_switch_screen).setVisibility(View.GONE);
+ return view;
+ }
+
+ @Override
+ public void onPlayerEvent(int eventCode, Bundle bundle) {
+ switch (eventCode){
+ case OnPlayerEventListener.PLAYER_EVENT_ON_DATA_SOURCE_SET:
+ mBufferPercentage = 0;
+ mTimeFormat = null;
+ updateUI(0, 0);
+ setBottomSeekBarState(true);
+ DataSource data = (DataSource) bundle.getSerializable(EventKey.SERIALIZABLE_DATA);
+ getGroupValue().putObject(DataInter.Key.KEY_DATA_SOURCE, data);
+ setTitle(data);
+ break;
+ case OnPlayerEventListener.PLAYER_EVENT_ON_STATUS_CHANGE:
+ int status = bundle.getInt(EventKey.INT_DATA);
+ if(status== IPlayer.STATE_PAUSED){
+ mStateIcon.setSelected(true);
+ }else if(status==IPlayer.STATE_STARTED){
+ mStateIcon.setSelected(false);
+ }
+ break;
+ case OnPlayerEventListener.PLAYER_EVENT_ON_PREPARED://某些机型没有render start这个消息
+ case OnPlayerEventListener.PLAYER_EVENT_ON_VIDEO_RENDER_START:
+ case OnPlayerEventListener.PLAYER_EVENT_ON_SEEK_COMPLETE:
+ mTimerUpdateProgressEnable = true;
+ break;
+ }
+ }
+
+ @Override
+ public void onErrorEvent(int eventCode, Bundle bundle) {
+
+ }
+
+ @Override
+ public void onReceiverEvent(int eventCode, Bundle bundle) {
+
+ }
+
+ private void updateUI(int curr, int duration) {
+ setSeekProgress(curr, duration);
+ setBottomSeekProgress(curr, duration);
+ setCurrTime(curr);
+ setTotalTime(duration);
+ }
+
+ private void setCurrTime(int curr){
+ mCurrTime.setText(TimeUtil.getTime(mTimeFormat, curr));
+ }
+
+ private void setTotalTime(int duration){
+ mTotalTime.setText(TimeUtil.getTime(mTimeFormat, duration));
+ }
+
+ private void setBottomSeekBarState(boolean state){
+ mBottomSeekBar.setVisibility(state?View.VISIBLE:View.GONE);
+ }
+
+ private void setTitle(DataSource dataSource){
+ if(dataSource!=null){
+ String title = dataSource.getTitle();
+ if(!TextUtils.isEmpty(title)){
+ setTitle(title);
+ return;
+ }
+ String data = dataSource.getData();
+ if(!TextUtils.isEmpty(data)){
+ setTitle(data);
+ }
+ }
+ }
+
+ private void setTitle(String text){
+ mTopTitle.setText(text);
+ }
+
+ private void setSeekProgress(int curr, int duration){
+ mSeekBar.setMax(duration);
+ mSeekBar.setProgress(curr);
+ float secondProgress = mBufferPercentage * 1.0f/100 * duration;
+ setSecondProgress((int) secondProgress);
+ }
+
+ private void setSecondProgress(int secondProgress){
+ mSeekBar.setSecondaryProgress(secondProgress);
+ }
+
+ private void setBottomSeekProgress(int curr, int duration){
+ mBottomSeekBar.setMax(duration);
+ mBottomSeekBar.setProgress(curr);
+ float secondProgress = mBufferPercentage * 1.0f/100 * duration;
+ mBottomSeekBar.setSecondaryProgress((int) secondProgress);
+ }
+
+ private void sendSeekEvent(int progress){
+ mTimerUpdateProgressEnable = false;
+ setCurrTime(progress);
+ int duration = getPlayerStateGetter().getDuration();
+ setSeekProgress(progress, duration);
+ setBottomContainerVisibility(true);
+ mSeekProgress = progress;
+ mHandler.removeCallbacks(mSeekEventRunnable);
+ mHandler.postDelayed(mSeekEventRunnable, 500);
+ }
+
+ private void setBottomContainerVisibility(boolean visibility){
+ int visible = visibility ? View.VISIBLE : View.GONE;
+ if (mBottomContainer.getVisibility() != visible) {
+ mBottomContainer.setVisibility(visible);
+ }
+ }
+ private Runnable mSeekEventRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if(mSeekProgress < 0)
+ return;
+ Bundle bundle = BundlePool.obtain();
+ bundle.putInt(EventKey.INT_DATA, mSeekProgress);
+ Log.d(TAG, "seek: " + mSeekProgress);
+ requestSeek(bundle);
+ mSeekProgress = -1;
+ boolean selected = mStateIcon.isSelected();
+ if (!selected) {
+ setBottomContainerVisibility(false);
+ }
+ }
+ };
+
+ @Override
+ public void onTimerUpdate(int curr, int duration, int bufferPercentage) {
+ if(!mTimerUpdateProgressEnable)
+ return;
+ if(mTimeFormat==null || duration != mSeekBar.getMax()){
+ mTimeFormat = TimeUtil.getFormat(duration);
+ }
+ mBufferPercentage = bufferPercentage;
+ updateUI(curr, duration);
+ }
+
+ /**----------- key control ------------------- */
+
+ @Override
+ protected void onBackKeyEvent(boolean down, KeyEvent event) {
+ if (!down) {
+ ((Activity) getContext()).finish();
+ }
+ }
+
+ @Override
+ protected void onCenterKeyEvent(boolean down, KeyEvent event) {
+ if (!down) {
+ boolean selected = mStateIcon.isSelected();
+ if(selected){
+ requestResume(null);
+ setBottomContainerVisibility(false);
+ }else{
+ requestPause(null);
+ setBottomContainerVisibility(true);
+ }
+ mStateIcon.setSelected(!selected);
+ }
+ }
+
+ @Override
+ protected void onLeftKeyEvent(boolean down, KeyEvent event) {
+ if (down) {
+ calculateSeekPosition(false);
+ }
+ }
+
+ @Override
+ protected void onRightKeyEvent(boolean down, KeyEvent event) {
+ if (down) {
+ calculateSeekPosition(true);
+ }
+ }
+
+ private void calculateSeekPosition(boolean right){
+ //-1代表不在快进状态中
+ int seekingProgress;
+ if (mSeekProgress == -1) {
+ seekingProgress = mSeekProgress = getPlayerStateGetter().getCurrentPosition();
+ } else {
+ seekingProgress = mSeekProgress;
+ }
+ Log.d(TAG, "calculateSeekPosition: " + seekingProgress);
+ if (right) {
+ seekingProgress += 500;
+ } else {
+ seekingProgress -= 500;
+ }
+ int duration = getPlayerStateGetter().getDuration();
+ //做一个前后判断,tv有些设备,seek到0或者duration的位置,会播放出错
+ if (seekingProgress > duration) {
+ seekingProgress = duration - 1000;
+ }
+ if (seekingProgress <= 0) {
+ seekingProgress = 500;
+ }
+ sendSeekEvent(seekingProgress);
+ }
+}
diff --git a/app/src/main/java/com/kk/taurus/avplayer/ui/TvBaseVideoViewActivity.java b/app/src/main/java/com/kk/taurus/avplayer/ui/TvBaseVideoViewActivity.java
new file mode 100644
index 00000000..f8a4b47a
--- /dev/null
+++ b/app/src/main/java/com/kk/taurus/avplayer/ui/TvBaseVideoViewActivity.java
@@ -0,0 +1,68 @@
+package com.kk.taurus.avplayer.ui;
+
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.kk.taurus.avplayer.cover.LoadingCover;
+import com.kk.taurus.avplayer.cover.TvControllerCover;
+import com.kk.taurus.avplayer.utils.DataUtils;
+import com.kk.taurus.playerbase.assist.OnVideoViewEventHandler;
+import com.kk.taurus.playerbase.entity.DataSource;
+import com.kk.taurus.playerbase.receiver.ReceiverGroup;
+import com.kk.taurus.playerbase.widget.BaseVideoView;
+
+import static com.kk.taurus.avplayer.play.DataInter.ReceiverKey.KEY_LOADING_COVER;
+
+public class TvBaseVideoViewActivity extends AppCompatActivity {
+
+ private BaseVideoView mVideoView;
+ private ReceiverGroup mReceiverGroup;
+
+ private boolean hasStart;
+ private boolean videoViewKeyEnable = true;
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mVideoView = new BaseVideoView(this);
+ mVideoView.setFocusable(true);
+ mVideoView.requestFocus();
+ mReceiverGroup = new ReceiverGroup();
+ mReceiverGroup.addReceiver(KEY_LOADING_COVER, new LoadingCover(this));
+ mReceiverGroup.addReceiver("key_event_cover", new TvControllerCover(this));
+ mVideoView.setReceiverGroup(mReceiverGroup);
+ mVideoView.setEventHandler(new OnVideoViewEventHandler());
+ setContentView(mVideoView);
+ initPlay();
+ }
+
+
+ private void initPlay(){
+ if(!hasStart){
+ DataSource dataSource = new DataSource(DataUtils.VIDEO_URL_09);
+ dataSource.setTitle("音乐和艺术如何改变世界");
+ mVideoView.setDataSource(dataSource);
+ mVideoView.start();
+ hasStart = true;
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_DOWN) {
+ videoViewKeyEnable = !videoViewKeyEnable;
+ mVideoView.getSuperContainer().setKeyEventEnable(videoViewKeyEnable);
+ Toast.makeText(this, videoViewKeyEnable ? "播放器可以分发" : "播放器移除分发", Toast.LENGTH_SHORT).show();
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mVideoView.stopPlayback();
+ }
+}
diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml
index 7bb5673f..710580e1 100644
--- a/app/src/main/res/layout/activity_home.xml
+++ b/app/src/main/res/layout/activity_home.xml
@@ -80,6 +80,18 @@
android:textSize="16sp"
android:textColor="@color/buttonTextColor"/>
+
+
+ android:layout_height="match_parent"
+ xmlns:tools="http://schemas.android.com/tools">
@@ -42,6 +44,7 @@
android:layout_width="match_parent"
android:layout_height="36dp"
android:visibility="gone"
+ tools:visibility="visible"
android:layout_alignParentBottom="true"
android:background="@drawable/shape_controller_bottom_gradient"
android:gravity="center_vertical"
@@ -104,6 +107,7 @@
android:paddingStart="0dp"
android:progressDrawable="@drawable/style_video_player_video_bottom_seekbar"
android:thumb="@null"
+ tools:visibility="visible"
android:visibility="gone" />
\ No newline at end of file
diff --git a/exoplayer/build.gradle b/exoplayer/build.gradle
index 51f2770e..67ddf40f 100644
--- a/exoplayer/build.gradle
+++ b/exoplayer/build.gradle
@@ -34,6 +34,6 @@ dependencies {
api 'com.google.android.exoplayer:exoplayer-dash:2.11.1'
api 'com.google.android.exoplayer:exoplayer-hls:2.11.1'
api 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.11.1'
- api 'com.kk.taurus.playerbase:playerbase:3.3.6'
-// api project(':playerbase')
+// api 'com.kk.taurus.playerbase:playerbase:3.3.6'
+ api project(':playerbase')
}
\ No newline at end of file
diff --git a/ijkplayer/build.gradle b/ijkplayer/build.gradle
index 7959b3bb..fda4b486 100644
--- a/ijkplayer/build.gradle
+++ b/ijkplayer/build.gradle
@@ -31,6 +31,6 @@ dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
api 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
- api 'com.kk.taurus.playerbase:playerbase:3.3.6'
-// api project(':playerbase')
+// api 'com.kk.taurus.playerbase:playerbase:3.3.6'
+ api project(':playerbase')
}
diff --git a/playerbase/src/main/java/com/kk/taurus/playerbase/event/EventDispatcher.java b/playerbase/src/main/java/com/kk/taurus/playerbase/event/EventDispatcher.java
index 33b38d26..462e35c6 100644
--- a/playerbase/src/main/java/com/kk/taurus/playerbase/event/EventDispatcher.java
+++ b/playerbase/src/main/java/com/kk/taurus/playerbase/event/EventDispatcher.java
@@ -17,12 +17,14 @@
package com.kk.taurus.playerbase.event;
import android.os.Bundle;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import com.kk.taurus.playerbase.log.DebugLog;
import com.kk.taurus.playerbase.player.OnTimerUpdateListener;
import com.kk.taurus.playerbase.receiver.IReceiver;
import com.kk.taurus.playerbase.receiver.IReceiverGroup;
+import com.kk.taurus.playerbase.touch.OnKeyEventListener;
import com.kk.taurus.playerbase.touch.OnTouchGestureListener;
/**
@@ -210,6 +212,26 @@ public void onEach(IReceiver receiver) {
});
}
+ @Override
+ public void dispatchKeyDownEvent(final int keyCode, final KeyEvent event) {
+ filterImplOnKeyEventListener(new IReceiverGroup.OnLoopListener() {
+ @Override
+ public void onEach(IReceiver receiver) {
+ ((OnKeyEventListener) receiver).onKeyDownInCover(keyCode, event);
+ }
+ });
+ }
+
+ @Override
+ public void dispatchKeyUpEvent(final int keyCode, final KeyEvent event) {
+ filterImplOnKeyEventListener(new IReceiverGroup.OnLoopListener() {
+ @Override
+ public void onEach(IReceiver receiver) {
+ ((OnKeyEventListener) receiver).onKeyUpInCover(keyCode, event);
+ }
+ });
+ }
+
private void filterImplOnTouchEventListener(final IReceiverGroup.OnLoopListener onLoopListener){
mReceiverGroup.forEach(new IReceiverGroup.OnReceiverFilter() {
@Override
@@ -224,6 +246,20 @@ public void onEach(IReceiver receiver) {
});
}
+ private void filterImplOnKeyEventListener(final IReceiverGroup.OnLoopListener onLoopListener){
+ mReceiverGroup.forEach(new IReceiverGroup.OnReceiverFilter() {
+ @Override
+ public boolean filter(IReceiver receiver) {
+ return receiver instanceof OnKeyEventListener;
+ }
+ }, new IReceiverGroup.OnLoopListener() {
+ @Override
+ public void onEach(IReceiver receiver) {
+ onLoopListener.onEach(receiver);
+ }
+ });
+ }
+
private void recycleBundle(Bundle bundle){
if(bundle!=null)
bundle.clear();
diff --git a/playerbase/src/main/java/com/kk/taurus/playerbase/event/IEventDispatcher.java b/playerbase/src/main/java/com/kk/taurus/playerbase/event/IEventDispatcher.java
index 7944e02d..6e968bea 100644
--- a/playerbase/src/main/java/com/kk/taurus/playerbase/event/IEventDispatcher.java
+++ b/playerbase/src/main/java/com/kk/taurus/playerbase/event/IEventDispatcher.java
@@ -17,6 +17,7 @@
package com.kk.taurus.playerbase.event;
import android.os.Bundle;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import com.kk.taurus.playerbase.receiver.IReceiverGroup;
@@ -40,4 +41,7 @@ public interface IEventDispatcher {
void dispatchTouchEventOnDown(MotionEvent event);
void dispatchTouchEventOnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
void dispatchTouchEventOnEndGesture();
+
+ void dispatchKeyDownEvent(int keyCode, KeyEvent event);
+ void dispatchKeyUpEvent(int keyCode, KeyEvent event);
}
diff --git a/playerbase/src/main/java/com/kk/taurus/playerbase/touch/ContainerKeyEventHelper.java b/playerbase/src/main/java/com/kk/taurus/playerbase/touch/ContainerKeyEventHelper.java
new file mode 100644
index 00000000..e40262c7
--- /dev/null
+++ b/playerbase/src/main/java/com/kk/taurus/playerbase/touch/ContainerKeyEventHelper.java
@@ -0,0 +1,31 @@
+package com.kk.taurus.playerbase.touch;
+
+import android.view.KeyEvent;
+
+public class ContainerKeyEventHelper {
+ private OnKeyEventListener mOnKeyEventListener;
+
+ private Boolean mKeyEnable = true;
+
+ public ContainerKeyEventHelper(OnKeyEventListener onKeyEventListener){
+ this.mOnKeyEventListener = onKeyEventListener;
+ }
+
+ public void setKeyEventEnable(boolean enable) {
+ mKeyEnable = enable;
+ }
+
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (mKeyEnable && mOnKeyEventListener != null) {
+ mOnKeyEventListener.onKeyDownInCover(keyCode, event);
+ }
+ return mKeyEnable;
+ }
+
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (mKeyEnable && mOnKeyEventListener != null) {
+ mOnKeyEventListener.onKeyUpInCover(keyCode, event);
+ }
+ return mKeyEnable;
+ }
+}
diff --git a/playerbase/src/main/java/com/kk/taurus/playerbase/touch/OnKeyEventListener.java b/playerbase/src/main/java/com/kk/taurus/playerbase/touch/OnKeyEventListener.java
new file mode 100644
index 00000000..585d2c50
--- /dev/null
+++ b/playerbase/src/main/java/com/kk/taurus/playerbase/touch/OnKeyEventListener.java
@@ -0,0 +1,22 @@
+package com.kk.taurus.playerbase.touch;
+
+import android.view.KeyEvent;
+
+public interface OnKeyEventListener {
+ /**
+ * press any key
+ *
+ * @param keyCode A key code that represents the button pressed, from
+ * {@link KeyEvent}.
+ * @param event The KeyEvent object that defines the button action.
+ */
+ void onKeyDownInCover(int keyCode, KeyEvent event);
+
+ /**
+ * up any key
+ * @param keyCode A key code that represents the button pressed, from
+ * {@link KeyEvent}.
+ * @param event The KeyEvent object that defines the button action.
+ */
+ void onKeyUpInCover(int keyCode, KeyEvent event);
+}
diff --git a/playerbase/src/main/java/com/kk/taurus/playerbase/widget/BaseVideoView.java b/playerbase/src/main/java/com/kk/taurus/playerbase/widget/BaseVideoView.java
index 7bdba6d6..85257c2a 100644
--- a/playerbase/src/main/java/com/kk/taurus/playerbase/widget/BaseVideoView.java
+++ b/playerbase/src/main/java/com/kk/taurus/playerbase/widget/BaseVideoView.java
@@ -610,4 +610,14 @@ public void setElevationShadow(float elevation) {
public void setElevationShadow(int backgroundColor, float elevation) {
mStyleSetter.setElevationShadow(backgroundColor, elevation);
}
+
+ @Override
+ public void setFocusable(boolean focusable) {
+ mSuperContainer.setFocusable(focusable);
+ }
+
+ @Override
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
+ return mSuperContainer.requestFocus(direction, previouslyFocusedRect);
+ }
}
diff --git a/playerbase/src/main/java/com/kk/taurus/playerbase/widget/SuperContainer.java b/playerbase/src/main/java/com/kk/taurus/playerbase/widget/SuperContainer.java
index 02674f77..c2111bad 100644
--- a/playerbase/src/main/java/com/kk/taurus/playerbase/widget/SuperContainer.java
+++ b/playerbase/src/main/java/com/kk/taurus/playerbase/widget/SuperContainer.java
@@ -20,6 +20,7 @@
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.view.Gravity;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -34,6 +35,8 @@
import com.kk.taurus.playerbase.log.PLog;
import com.kk.taurus.playerbase.receiver.CoverComparator;
import com.kk.taurus.playerbase.receiver.StateGetter;
+import com.kk.taurus.playerbase.touch.ContainerKeyEventHelper;
+import com.kk.taurus.playerbase.touch.OnKeyEventListener;
import com.kk.taurus.playerbase.touch.OnTouchGestureListener;
import com.kk.taurus.playerbase.receiver.BaseCover;
import com.kk.taurus.playerbase.receiver.DefaultLevelCoverContainer;
@@ -50,7 +53,7 @@
* Created by Taurus on 2018/3/17.
*/
-public class SuperContainer extends FrameLayout implements OnTouchGestureListener {
+public class SuperContainer extends FrameLayout implements OnTouchGestureListener, OnKeyEventListener {
final String TAG = "SuperContainer";
@@ -62,6 +65,7 @@ public class SuperContainer extends FrameLayout implements OnTouchGestureListene
private OnReceiverEventListener mOnReceiverEventListener;
private ContainerTouchHelper mTouchHelper;
+ private ContainerKeyEventHelper mKeyHelper;
private IProducerGroup mProducerGroup;
@@ -86,6 +90,7 @@ private void initBaseInfo(Context context) {
protected void initGesture(Context context){
mTouchHelper = new ContainerTouchHelper(context,getGestureCallBackHandler());
setGestureEnable(true);
+ mKeyHelper = new ContainerKeyEventHelper(this);
}
@Override
@@ -93,6 +98,16 @@ public boolean onTouchEvent(MotionEvent event) {
return mTouchHelper.onTouch(event);
}
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return mKeyHelper.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return mKeyHelper.onKeyUp(keyCode, event);
+ }
+
protected BaseGestureCallbackHandler getGestureCallBackHandler(){
return new BaseGestureCallbackHandler(this);
}
@@ -105,6 +120,10 @@ public void setGestureScrollEnable(boolean enable) {
mTouchHelper.setGestureScrollEnable(enable);
}
+ public void setKeyEventEnable(boolean enable){
+ mKeyHelper.setKeyEventEnable(enable);
+ }
+
private void initReceiverContainer(Context context) {
mCoverStrategy = getCoverStrategy(context);
addView(mCoverStrategy.getContainerView(),
@@ -330,4 +349,16 @@ public void onEndGesture() {
if(mEventDispatcher!=null)
mEventDispatcher.dispatchTouchEventOnEndGesture();
}
+
+ @Override
+ public void onKeyDownInCover(int keyCode, KeyEvent event) {
+ if(mEventDispatcher!=null)
+ mEventDispatcher.dispatchKeyDownEvent(keyCode,event);
+ }
+
+ @Override
+ public void onKeyUpInCover(int keyCode, KeyEvent event) {
+ if(mEventDispatcher!=null)
+ mEventDispatcher.dispatchKeyUpEvent(keyCode,event);
+ }
}