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:
+ *
+ * -
+ * Show at least stream title and content creator on TVs and tablets
+ * when in landscape (always the case for TVs) and not in fullscreen mode.
+ * This requires to have at least
85dp
free space for {@link R.id.detail_root}
+ * and additional space for the stream title text size
+ * ({@link R.id.detail_title_root_layout}).
+ * The text size is 15sp
on tablets and 16sp
on TVs,
+ * see {@link R.id.titleTextView}.
+ *
+ * -
+ * Otherwise, the max thumbnail height is the screen height.
+ *
+ *
+ *
+ * @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());
+ }
}