From 465ed86d34bf08bd63fb641d5bc9080cddc51adf Mon Sep 17 00:00:00 2001 From: FongMi Date: Sat, 14 Jun 2025 17:45:08 +0800 Subject: [PATCH] Support scale video --- .../android/tv/ui/activity/LiveActivity.java | 2 + .../android/tv/ui/activity/VideoActivity.java | 4 ++ .../tv/ui/custom/CustomKeyDownLive.java | 52 +++++++++++++++++-- .../tv/ui/custom/CustomKeyDownVod.java | 52 +++++++++++++++++-- 4 files changed, 100 insertions(+), 10 deletions(-) diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java index f4981dd2f..bcb243a8d 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java @@ -213,6 +213,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List } private void setScale(int scale) { + mKeyDown.resetScale(); mBinding.exo.setResizeMode(scale); mBinding.control.action.scale.setText(ResUtil.getStringArray(R.array.select_scale)[scale]); } @@ -331,6 +332,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List private void onRotate() { setR1Callback(); + mKeyDown.resetScale(); setRotate(!isRotate()); setRequestedOrientation(ResUtil.isLand(this) ? ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 08495bc23..3a6b30529 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -398,6 +398,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo } private void setScale(int scale) { + mKeyDown.resetScale(); mBinding.exo.setResizeMode(scale); mBinding.control.action.scale.setText(ResUtil.getStringArray(R.array.select_scale)[scale]); } @@ -725,6 +726,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo private void onRotate() { setR1Callback(); + mKeyDown.resetScale(); setRotate(!isRotate()); setRequestedOrientation(ResUtil.isLand(this) ? ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } @@ -882,6 +884,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo setRotate(mPlayers.isPortrait(), true); mPlayers.setDanmakuSize(1.0f); Util.hideSystemUI(this); + mKeyDown.resetScale(); App.post(mR3, 2000); hideControl(); } @@ -894,6 +897,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo mBinding.video.setLayoutParams(mFrameParams); mPlayers.setDanmakuSize(0.8f); setRotate(false, false); + mKeyDown.resetScale(); App.post(mR3, 2000); hideControl(); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownLive.java b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownLive.java index 8653ed626..eefa53be6 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownLive.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownLive.java @@ -5,11 +5,13 @@ import android.content.Context; import android.media.AudioManager; import android.view.GestureDetector; import android.view.MotionEvent; +import android.view.ScaleGestureDetector; import android.view.View; import android.view.WindowManager; import androidx.annotation.NonNull; +import com.fongmi.android.tv.App; import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.Util; @@ -18,6 +20,7 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { private static final int DISTANCE = 250; private static final int VELOCITY = 10; + private final ScaleGestureDetector scaleDetector; private final GestureDetector detector; private final AudioManager manager; private final Listener listener; @@ -26,6 +29,7 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { private boolean changeBright; private boolean changeVolume; private boolean changeSpeed; + private boolean changeScale; private boolean changeTime; private boolean animating; private boolean center; @@ -33,6 +37,7 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { private boolean lock; private float bright; private float volume; + private float scale; private long time; public static CustomKeyDownLive create(Activity activity, View videoView) { @@ -41,10 +46,12 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { private CustomKeyDownLive(Activity activity, View videoView) { this.manager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE); + this.scaleDetector = new ScaleGestureDetector(activity, new ScaleListener()); this.detector = new GestureDetector(activity, this); this.listener = (Listener) activity; this.videoView = videoView; this.activity = activity; + this.scale = 1.0f; } public boolean onTouchEvent(MotionEvent e) { @@ -52,7 +59,15 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { if (changeSpeed && e.getAction() == MotionEvent.ACTION_UP) listener.onSpeedEnd(); if (changeBright && e.getAction() == MotionEvent.ACTION_UP) listener.onBrightEnd(); if (changeVolume && e.getAction() == MotionEvent.ACTION_UP) listener.onVolumeEnd(); - return detector.onTouchEvent(e); + return e.getPointerCount() == 2 ? scaleDetector.onTouchEvent(e) : detector.onTouchEvent(e); + } + + public void resetScale() { + scale = 1.0f; + videoView.setScaleX(1.0f); + videoView.setScaleY(1.0f); + videoView.setPivotX(videoView.getWidth() / 2f); + videoView.setPivotY(videoView.getHeight() / 2f); } public void setLock(boolean lock) { @@ -65,7 +80,7 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(@NonNull MotionEvent e) { - if (isEdge(e) || lock || e.getPointerCount() > 1) return true; + if (isEdge(e) || changeScale || lock || e.getPointerCount() > 1) return true; volume = manager.getStreamVolume(AudioManager.STREAM_MUSIC); bright = Util.getBrightness(activity); changeBright = false; @@ -79,14 +94,14 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { @Override public void onLongPress(@NonNull MotionEvent e) { - if (isEdge(e) || lock || e.getPointerCount() > 1) return; + if (isEdge(e) || changeScale || lock || e.getPointerCount() > 1) return; changeSpeed = true; listener.onSpeedUp(); } @Override public boolean onScroll(MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) { - if (isEdge(e1) || lock || e1.getPointerCount() > 1) return true; + if (isEdge(e1) || changeScale || lock || e1.getPointerCount() > 1) return true; float deltaX = e2.getX() - e1.getX(); float deltaY = e1.getY() - e2.getY(); if (touch) checkFunc(distanceX, distanceY, e2); @@ -98,12 +113,14 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(@NonNull MotionEvent e) { + if (isEdge(e) || changeScale || e.getPointerCount() > 1) return true; listener.onDoubleTap(); return true; } @Override public boolean onSingleTapConfirmed(@NonNull MotionEvent e) { + if (isEdge(e) || changeScale || e.getPointerCount() > 1) return true; int half = ResUtil.getScreenWidth(activity) / 2; if (e.getX() > half || lock) listener.onDoubleTap(); else listener.onSingleTap(); @@ -112,7 +129,7 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) { - if (isEdge(e1) || !center || animating) return true; + if (isEdge(e1) || changeScale || !center || animating || e1.getPointerCount() > 1) return true; checkFunc(e1, e2, velocityX, velocityY); return true; } @@ -172,6 +189,31 @@ public class CustomKeyDownLive extends GestureDetector.SimpleOnGestureListener { listener.onVolume((int) (index / maxVolume * 100)); } + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScaleBegin(@NonNull ScaleGestureDetector detector) { + if (changeBright || changeVolume || changeSpeed || changeTime || lock) return false; + return changeScale = true; + } + + @Override + public void onScaleEnd(@NonNull ScaleGestureDetector detector) { + App.post(() -> changeScale = false, 250); + } + + @Override + public boolean onScale(@NonNull ScaleGestureDetector detector) { + if (!changeScale) return false; + scale *= detector.getScaleFactor(); + scale = Math.max(1.0f, Math.min(scale, 5.0f)); + videoView.setPivotX(detector.getFocusX()); + videoView.setPivotY(detector.getFocusY()); + videoView.setScaleX(scale); + videoView.setScaleY(scale); + return true; + } + } + public interface Listener { void onSpeedUp(); diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownVod.java b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownVod.java index d3daed8c8..e1dc20682 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownVod.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/CustomKeyDownVod.java @@ -5,11 +5,13 @@ import android.content.Context; import android.media.AudioManager; import android.view.GestureDetector; import android.view.MotionEvent; +import android.view.ScaleGestureDetector; import android.view.View; import android.view.WindowManager; import androidx.annotation.NonNull; +import com.fongmi.android.tv.App; import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.Util; @@ -18,6 +20,7 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { private static final int DISTANCE = 250; private static final int VELOCITY = 10; + private final ScaleGestureDetector scaleDetector; private final GestureDetector detector; private final AudioManager manager; private final Listener listener; @@ -26,6 +29,7 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { private boolean changeBright; private boolean changeVolume; private boolean changeSpeed; + private boolean changeScale; private boolean changeTime; private boolean animating; private boolean center; @@ -33,6 +37,7 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { private boolean lock; private float bright; private float volume; + private float scale; private long time; public static CustomKeyDownVod create(Activity activity, View videoView) { @@ -41,10 +46,12 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { private CustomKeyDownVod(Activity activity, View videoView) { this.manager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE); + this.scaleDetector = new ScaleGestureDetector(activity, new ScaleListener()); this.detector = new GestureDetector(activity, this); this.listener = (Listener) activity; this.videoView = videoView; this.activity = activity; + this.scale = 1.0f; } public boolean onTouchEvent(MotionEvent e) { @@ -52,7 +59,15 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { if (changeSpeed && e.getAction() == MotionEvent.ACTION_UP) listener.onSpeedEnd(); if (changeBright && e.getAction() == MotionEvent.ACTION_UP) listener.onBrightEnd(); if (changeVolume && e.getAction() == MotionEvent.ACTION_UP) listener.onVolumeEnd(); - return detector.onTouchEvent(e); + return e.getPointerCount() == 2 ? scaleDetector.onTouchEvent(e) : detector.onTouchEvent(e); + } + + public void resetScale() { + scale = 1.0f; + videoView.setScaleX(1.0f); + videoView.setScaleY(1.0f); + videoView.setPivotX(videoView.getWidth() / 2f); + videoView.setPivotY(videoView.getHeight() / 2f); } public void setLock(boolean lock) { @@ -65,7 +80,7 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDown(@NonNull MotionEvent e) { - if (isEdge(e) || lock || e.getPointerCount() > 1) return true; + if (isEdge(e) || changeScale || lock || e.getPointerCount() > 1) return true; volume = manager.getStreamVolume(AudioManager.STREAM_MUSIC); bright = Util.getBrightness(activity); changeBright = false; @@ -79,14 +94,14 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { @Override public void onLongPress(@NonNull MotionEvent e) { - if (isEdge(e) || lock || e.getPointerCount() > 1) return; + if (isEdge(e) || changeScale || lock || e.getPointerCount() > 1) return; changeSpeed = true; listener.onSpeedUp(); } @Override public boolean onScroll(MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) { - if (isEdge(e1) || lock || e1.getPointerCount() > 1) return true; + if (isEdge(e1) || changeScale || lock || e1.getPointerCount() > 1) return true; float deltaX = e2.getX() - e1.getX(); float deltaY = e1.getY() - e2.getY(); if (touch) checkFunc(distanceX, distanceY, e2); @@ -98,19 +113,21 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(@NonNull MotionEvent e) { + if (isEdge(e) || changeScale || e.getPointerCount() > 1) return true; if (!lock) listener.onDoubleTap(); return true; } @Override public boolean onSingleTapConfirmed(@NonNull MotionEvent e) { + if (isEdge(e) || changeScale || e.getPointerCount() > 1) return true; listener.onSingleTap(); return true; } @Override public boolean onFling(MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) { - if (isEdge(e1) || !center || animating) return true; + if (isEdge(e1) || changeScale || !center || animating || e1.getPointerCount() > 1) return true; checkFunc(e1, e2, velocityY); return true; } @@ -166,6 +183,31 @@ public class CustomKeyDownVod extends GestureDetector.SimpleOnGestureListener { listener.onVolume((int) (index / maxVolume * 100)); } + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScaleBegin(@NonNull ScaleGestureDetector detector) { + if (changeBright || changeVolume || changeSpeed || changeTime || lock) return false; + return changeScale = true; + } + + @Override + public void onScaleEnd(@NonNull ScaleGestureDetector detector) { + App.post(() -> changeScale = false, 250); + } + + @Override + public boolean onScale(@NonNull ScaleGestureDetector detector) { + if (!changeScale) return false; + scale *= detector.getScaleFactor(); + scale = Math.max(1.0f, Math.min(scale, 5.0f)); + videoView.setPivotX(detector.getFocusX()); + videoView.setPivotY(detector.getFocusY()); + videoView.setScaleX(scale); + videoView.setScaleY(scale); + return true; + } + } + public interface Listener { void onSpeedUp();