diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 424775928..ab93d8742 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1129,6 +1129,12 @@ public final class Player implements // Close it because when changing orientation from portrait // (in fullscreen mode) the size of queue layout can be larger than the screen size closeItemsList(); + // When the orientation changed, the screen height might be smaller. + // If the end screen thumbnail is not re-scaled, + // it can be larger than the current screen height + // and thus enlarging the whole player. + // This causes the seekbar to be ouf the visible area. + updateEndScreenThumbnail(); break; case Intent.ACTION_SCREEN_ON: // Interrupt playback only when screen turns on @@ -1187,6 +1193,78 @@ public final class Player implements .loadImage(url, ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, this); } + /** + * Scale the player audio / end screen thumbnail down if necessary. + *

+ * This is necessary when the thumbnail's height is larger than the device's height + * and thus is enlarging the player's height + * causing the bottom playback controls to be out of the visible screen. + *

+ */ + public void updateEndScreenThumbnail() { + if (currentThumbnail == null) { + return; + } + + final float endScreenHeight = calculateMaxEndScreenThumbnailHeight(); + + final Bitmap endScreenBitmap = Bitmap.createScaledBitmap( + currentThumbnail, + (int) (currentThumbnail.getWidth() + / (currentThumbnail.getHeight() / endScreenHeight)), + (int) endScreenHeight, + true); + + if (DEBUG) { + Log.d(TAG, "Thumbnail - updateEndScreenThumbnail() called with: " + + "currentThumbnail = [" + currentThumbnail + "], " + + currentThumbnail.getWidth() + "x" + currentThumbnail.getHeight() + + ", scaled end screen height = " + endScreenHeight + + ", scaled end screen width = " + endScreenBitmap.getWidth()); + } + + binding.endScreen.setImageBitmap(endScreenBitmap); + } + + /** + * Calculate the maximum allowed height for the {@link R.id.endScreen} + * to prevent it from enlarging the player. + *

+ * The calculating follows these rules: + *

+ * + * @return the maximum height for the end screen thumbnail + */ + private float calculateMaxEndScreenThumbnailHeight() { + // ensure that screenHeight is initialized and thus not 0 + updateScreenSize(); + + if (DeviceUtils.isTv(context) && !isFullscreen) { + final int videoInfoHeight = + DeviceUtils.dpToPx(85, context) + DeviceUtils.spToPx(16, context); + return Math.min(currentThumbnail.getHeight(), screenHeight - videoInfoHeight); + } else if (DeviceUtils.isTablet(context) && service.isLandscape() && !isFullscreen) { + final int videoInfoHeight = + DeviceUtils.dpToPx(85, context) + DeviceUtils.spToPx(15, context); + return Math.min(currentThumbnail.getHeight(), screenHeight - videoInfoHeight); + } else { // fullscreen player: max height is the device height + return Math.min(currentThumbnail.getHeight(), screenHeight); + } + } + @Override public void onLoadingStarted(final String imageUri, final View view) { if (DEBUG) { @@ -1207,23 +1285,29 @@ public final class Player implements @Override public void onLoadingComplete(final String imageUri, final View view, final Bitmap loadedImage) { - final float width = Math.min( + // scale down the notification thumbnail for performance + final float notificationThumbnailWidth = Math.min( context.getResources().getDimension(R.dimen.player_notification_thumbnail_width), loadedImage.getWidth()); + currentThumbnail = Bitmap.createScaledBitmap( + loadedImage, + (int) notificationThumbnailWidth, + (int) (loadedImage.getHeight() + / (loadedImage.getWidth() / notificationThumbnailWidth)), + true); if (DEBUG) { Log.d(TAG, "Thumbnail - onLoadingComplete() called with: " + "imageUri = [" + imageUri + "], view = [" + view + "], " + "loadedImage = [" + loadedImage + "], " + loadedImage.getWidth() + "x" + loadedImage.getHeight() - + ", scaled width = " + width); + + ", scaled notification width = " + notificationThumbnailWidth); } - currentThumbnail = Bitmap.createScaledBitmap(loadedImage, - (int) width, - (int) (loadedImage.getHeight() / (loadedImage.getWidth() / width)), true); - binding.endScreen.setImageBitmap(loadedImage); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); + + // there is a new thumbnail, thus the end screen thumbnail needs to be changed, too. + updateEndScreenThumbnail(); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index 1afedcaef..52069fd0e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -6,8 +6,10 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.os.BatteryManager; import android.os.Build; +import android.util.TypedValue; import android.view.KeyEvent; +import androidx.annotation.Dimension; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; @@ -70,4 +72,20 @@ public final class DeviceUtils { return false; } } + + public static int dpToPx(@Dimension(unit = Dimension.DP) final int dp, + @NonNull final Context context) { + return (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + dp, + context.getResources().getDisplayMetrics()); + } + + public static int spToPx(@Dimension(unit = Dimension.SP) final int sp, + @NonNull final Context context) { + return (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + sp, + context.getResources().getDisplayMetrics()); + } }