Skip to content

Commit 71d3227

Browse files
committed
Fix bottom controls being out of the screen
This was caused by too large end screen thumbnails enlarging the whole palyer. Fixed by scaling the thumbnail. Ensure that the player does not use the whole screen height in detail fragment to keep the additional content like title, comments, etc. available.
1 parent a28aa6a commit 71d3227

2 files changed

Lines changed: 108 additions & 6 deletions

File tree

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,12 @@ private void onBroadcastReceived(final Intent intent) {
11291129
// Close it because when changing orientation from portrait
11301130
// (in fullscreen mode) the size of queue layout can be larger than the screen size
11311131
closeItemsList();
1132+
// When the orientation changed, the screen height might be smaller.
1133+
// If the end screen thumbnail is not re-scaled,
1134+
// it can be larger than the current screen height
1135+
// and thus enlarging the whole player.
1136+
// This causes the seekbar to be ouf the visible area.
1137+
updateEndScreenThumbnail();
11321138
break;
11331139
case Intent.ACTION_SCREEN_ON:
11341140
// Interrupt playback only when screen turns on
@@ -1187,6 +1193,78 @@ private void initThumbnail(final String url) {
11871193
.loadImage(url, ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, this);
11881194
}
11891195

1196+
/**
1197+
* Scale the player audio / end screen thumbnail down if necessary.
1198+
* <p>
1199+
* This is necessary when the thumbnail's height is larger than the device's height
1200+
* and thus is enlarging the player's height
1201+
* causing the bottom playback controls to be out of the visible screen.
1202+
* </p>
1203+
*/
1204+
public void updateEndScreenThumbnail() {
1205+
if (currentThumbnail == null) {
1206+
return;
1207+
}
1208+
1209+
final float endScreenHeight = calculateMaxEndScreenThumbnailHeight();
1210+
1211+
final Bitmap endScreenBitmap = Bitmap.createScaledBitmap(
1212+
currentThumbnail,
1213+
(int) (currentThumbnail.getWidth()
1214+
/ (currentThumbnail.getHeight() / endScreenHeight)),
1215+
(int) endScreenHeight,
1216+
true);
1217+
1218+
if (DEBUG) {
1219+
Log.d(TAG, "Thumbnail - updateEndScreenThumbnail() called with: "
1220+
+ "currentThumbnail = [" + currentThumbnail + "], "
1221+
+ currentThumbnail.getWidth() + "x" + currentThumbnail.getHeight()
1222+
+ ", scaled end screen height = " + endScreenHeight
1223+
+ ", scaled end screen width = " + endScreenBitmap.getWidth());
1224+
}
1225+
1226+
binding.endScreen.setImageBitmap(endScreenBitmap);
1227+
}
1228+
1229+
/**
1230+
* Calculate the maximum allowed height for the {@link R.id.endScreen}
1231+
* to prevent it from enlarging the player.
1232+
* <p>
1233+
* The calculating follows these rules:
1234+
* <ul>
1235+
* <li>
1236+
* Show at least stream title and content creator on TVs and tablets
1237+
* when in landscape (always the case for TVs) and not in fullscreen mode.
1238+
* This requires to have at least <code>85dp</code> free space for {@link R.id.detail_root}
1239+
* and additional space for the stream title text size
1240+
* ({@link R.id.detail_title_root_layout}).
1241+
* The text size is <code>15sp</code> on tablets and <code>16sp</code> on TVs,
1242+
* see {@link R.id.titleTextView}.
1243+
* </li>
1244+
* <li>
1245+
* Otherwise, the max thumbnail height is the screen height.
1246+
* </li>
1247+
* </ul>
1248+
*
1249+
* @return the maximum height for the end screen thumbnail
1250+
*/
1251+
private float calculateMaxEndScreenThumbnailHeight() {
1252+
// ensure that screenHeight is initialized and thus not 0
1253+
updateScreenSize();
1254+
1255+
if (DeviceUtils.isTv(context) && !isFullscreen) {
1256+
final int videoInfoHeight =
1257+
DeviceUtils.dpToPx(85, context) + DeviceUtils.spToPx(16, context);
1258+
return Math.min(currentThumbnail.getHeight(), screenHeight - videoInfoHeight);
1259+
} else if (DeviceUtils.isTablet(context) && service.isLandscape() && !isFullscreen) {
1260+
final int videoInfoHeight =
1261+
DeviceUtils.dpToPx(85, context) + DeviceUtils.spToPx(15, context);
1262+
return Math.min(currentThumbnail.getHeight(), screenHeight - videoInfoHeight);
1263+
} else { // fullscreen player: max height is the device height
1264+
return Math.min(currentThumbnail.getHeight(), screenHeight);
1265+
}
1266+
}
1267+
11901268
@Override
11911269
public void onLoadingStarted(final String imageUri, final View view) {
11921270
if (DEBUG) {
@@ -1207,23 +1285,29 @@ public void onLoadingFailed(final String imageUri, final View view,
12071285
@Override
12081286
public void onLoadingComplete(final String imageUri, final View view,
12091287
final Bitmap loadedImage) {
1210-
final float width = Math.min(
1288+
// scale down the notification thumbnail for performance
1289+
final float notificationThumbnailWidth = Math.min(
12111290
context.getResources().getDimension(R.dimen.player_notification_thumbnail_width),
12121291
loadedImage.getWidth());
1292+
currentThumbnail = Bitmap.createScaledBitmap(
1293+
loadedImage,
1294+
(int) notificationThumbnailWidth,
1295+
(int) (loadedImage.getHeight()
1296+
/ (loadedImage.getWidth() / notificationThumbnailWidth)),
1297+
true);
12131298

12141299
if (DEBUG) {
12151300
Log.d(TAG, "Thumbnail - onLoadingComplete() called with: "
12161301
+ "imageUri = [" + imageUri + "], view = [" + view + "], "
12171302
+ "loadedImage = [" + loadedImage + "], "
12181303
+ loadedImage.getWidth() + "x" + loadedImage.getHeight()
1219-
+ ", scaled width = " + width);
1304+
+ ", scaled notification width = " + notificationThumbnailWidth);
12201305
}
12211306

1222-
currentThumbnail = Bitmap.createScaledBitmap(loadedImage,
1223-
(int) width,
1224-
(int) (loadedImage.getHeight() / (loadedImage.getWidth() / width)), true);
1225-
binding.endScreen.setImageBitmap(loadedImage);
12261307
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
1308+
1309+
// there is a new thumbnail, thus the end screen thumbnail needs to be changed, too.
1310+
updateEndScreenThumbnail();
12271311
}
12281312

12291313
@Override

app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
import android.content.res.Configuration;
77
import android.os.BatteryManager;
88
import android.os.Build;
9+
import android.util.TypedValue;
910
import android.view.KeyEvent;
1011

12+
import androidx.annotation.Dimension;
1113
import androidx.annotation.NonNull;
1214
import androidx.core.content.ContextCompat;
1315

@@ -70,4 +72,20 @@ public static boolean isConfirmKey(final int keyCode) {
7072
return false;
7173
}
7274
}
75+
76+
public static int dpToPx(@Dimension(unit = Dimension.DP) final int dp,
77+
@NonNull final Context context) {
78+
return (int) TypedValue.applyDimension(
79+
TypedValue.COMPLEX_UNIT_DIP,
80+
dp,
81+
context.getResources().getDisplayMetrics());
82+
}
83+
84+
public static int spToPx(@Dimension(unit = Dimension.SP) final int sp,
85+
@NonNull final Context context) {
86+
return (int) TypedValue.applyDimension(
87+
TypedValue.COMPLEX_UNIT_SP,
88+
sp,
89+
context.getResources().getDisplayMetrics());
90+
}
7391
}

0 commit comments

Comments
 (0)