From 0abc65a9bd7eca286147a25fb7ce2b7a75821241 Mon Sep 17 00:00:00 2001 From: Koen J Date: Mon, 1 Dec 2025 11:51:26 +0100 Subject: [PATCH] Downsample if larger than 1080x1080 to prevent crashing. --- .../java/com/futo/platformplayer/Utility.kt | 20 +------------------ .../main/RemotePlaylistFragment.kt | 2 ++ .../fragment/mainactivity/main/ShortView.kt | 11 +++++++--- .../mainactivity/main/VideoDetailView.kt | 3 ++- .../mainactivity/main/VideoListEditorView.kt | 2 ++ .../futo/platformplayer/images/GlideHelper.kt | 3 ++- .../services/MediaPlaybackService.kt | 2 ++ .../states/StateNotifications.kt | 2 ++ .../views/adapters/PlaylistsViewHolder.kt | 2 ++ .../adapters/VideoListEditorViewHolder.kt | 2 ++ .../viewholders/LocalVideoTileViewHolder.kt | 2 ++ .../platformplayer/views/casting/CastView.kt | 2 ++ .../views/items/ActiveDownloadItem.kt | 2 ++ .../views/items/PlaylistDownloadItem.kt | 2 ++ .../views/video/FutoThumbnailPlayer.kt | 3 ++- .../views/videometa/UpNextView.kt | 2 ++ 16 files changed, 37 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/Utility.kt b/app/src/main/java/com/futo/platformplayer/Utility.kt index 5b00bbb9..108fd93e 100644 --- a/app/src/main/java/com/futo/platformplayer/Utility.kt +++ b/app/src/main/java/com/futo/platformplayer/Utility.kt @@ -5,8 +5,6 @@ import android.content.Context import android.content.Intent import android.content.res.Resources import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.icu.util.Output import android.os.Build import android.os.Looper import android.os.OperationCanceledException @@ -44,6 +42,7 @@ import java.util.* import java.util.concurrent.ThreadLocalRandom import java.util.zip.GZIPInputStream import java.util.zip.GZIPOutputStream +import androidx.core.graphics.scale private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "; fun getRandomString(sizeOfRandomString: Int): String { @@ -114,23 +113,6 @@ fun DocumentFile.writeBytes(context: Context, byteArray: ByteArray) = context.co it.flush(); }; -fun loadBitmap(url: String): Bitmap { - try { - val client = ManagedHttpClient(); - val response = client.get(url); - if (response.isOk && response.body != null) { - val bitmapStream = response.body.byteStream(); - val bitmap = BitmapFactory.decodeStream(bitmapStream); - return bitmap; - } else { - throw Exception("Failed to find data at URL."); - } - } catch (e: Throwable) { - Logger.w("Utility", "Exception thrown while downloading bitmap.", e); - throw e; - } -} - fun TextView.setPlatformPlayerLinkMovementMethod(context: Context) { this.movementMethod = PlatformLinkMovementMethod(context); } diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/RemotePlaylistFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/RemotePlaylistFragment.kt index 349b4fb0..7e819f72 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/RemotePlaylistFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/RemotePlaylistFragment.kt @@ -16,6 +16,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.* import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylist import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylistDetails @@ -363,6 +364,7 @@ class RemotePlaylistFragment : MainFragment() { _imagePlaylistThumbnail.let { Glide.with(it) .load(video.thumbnails.getHQThumbnail()) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .placeholder(R.drawable.placeholder_video_thumbnail) .crossfade() .into(it); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt index e3a0a655..19be4777 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt @@ -2,7 +2,9 @@ package com.futo.platformplayer.fragment.mainactivity.main import android.content.Context import android.content.Intent +import android.graphics.Bitmap import android.graphics.drawable.Animatable +import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.LayoutInflater import android.view.WindowManager @@ -13,10 +15,15 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.graphics.drawable.toDrawable import androidx.lifecycle.lifecycleScope import androidx.media3.common.C import androidx.media3.common.Format import androidx.media3.common.util.UnstableApi +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy +import com.bumptech.glide.request.target.CustomTarget +import com.bumptech.glide.request.transition.Transition import com.futo.platformplayer.R import com.futo.platformplayer.Settings import com.futo.platformplayer.UIDialogs @@ -851,9 +858,8 @@ class ShortView : FrameLayout { } val thumbnail = videoDetails.thumbnails.getHQThumbnail() - /* if (videoSource == null && !thumbnail.isNullOrBlank()) Glide.with(context).asBitmap() - .load(thumbnail).into(object : CustomTarget() { + .load(thumbnail).downsample(DownsampleStrategy.AT_MOST).override(1080, 1080).into(object : CustomTarget() { override fun onResourceReady(resource: Bitmap, transition: Transition?) { player.setArtwork(resource.toDrawable(resources)) } @@ -863,7 +869,6 @@ class ShortView : FrameLayout { } }) else player.setArtwork(null) - */ fragment.lifecycleScope.launch(Dispatchers.Main) { try { diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index d3558c07..3e9319a7 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -42,6 +42,7 @@ import androidx.media3.datasource.HttpDataSource import androidx.media3.ui.PlayerControlView import androidx.media3.ui.TimeBar import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition import com.futo.platformplayer.BuildConfig @@ -2049,7 +2050,7 @@ class VideoDetailView : ConstraintLayout { } else { val thumbnail = video.thumbnails.getHQThumbnail(); if ((videoSource == null) && !thumbnail.isNullOrBlank()) // || _player.isAudioMode - Glide.with(context).asBitmap().load(thumbnail) + Glide.with(context).asBitmap().load(thumbnail).downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .into(object: CustomTarget() { override fun onResourceReady(resource: Bitmap, transition: Transition?) { _player.setArtwork(BitmapDrawable(resources, resource)); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoListEditorView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoListEditorView.kt index ae890d94..9ae8eeea 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoListEditorView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoListEditorView.kt @@ -14,6 +14,7 @@ import android.widget.TextView import androidx.core.view.isVisible import androidx.core.view.setPadding import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.R import com.futo.platformplayer.UIDialogs import com.futo.platformplayer.UISlideOverlays @@ -211,6 +212,7 @@ abstract class VideoListEditorView : LinearLayout { _imagePlaylistThumbnail.let { Glide.with(it) .load(video.thumbnails.getHQThumbnail()) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .placeholder(R.drawable.placeholder_video_thumbnail) .crossfade() .into(it); diff --git a/app/src/main/java/com/futo/platformplayer/images/GlideHelper.kt b/app/src/main/java/com/futo/platformplayer/images/GlideHelper.kt index 4b98cdeb..bb0cdf38 100644 --- a/app/src/main/java/com/futo/platformplayer/images/GlideHelper.kt +++ b/app/src/main/java/com/futo/platformplayer/images/GlideHelper.kt @@ -4,6 +4,7 @@ import android.graphics.drawable.Drawable import android.widget.ImageView import com.bumptech.glide.Glide import com.bumptech.glide.RequestBuilder +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.futo.platformplayer.api.media.models.Thumbnails @@ -14,7 +15,7 @@ class GlideHelper { fun ImageView.loadThumbnails(thumbnails: Thumbnails, isHQ: Boolean = true, continuation: ((RequestBuilder) -> Unit)? = null) { val url = if(isHQ) thumbnails.getHQThumbnail() ?: thumbnails.getLQThumbnail() else thumbnails.getLQThumbnail(); - val req = Glide.with(this).load(url); + val req = Glide.with(this).load(url).downsample(DownsampleStrategy.AT_MOST).override(1080, 1080); if (thumbnails.hasMultiple() && false) { //TODO: Resolve issue where fallback triggered on second loads? val fallbackUrl = if (isHQ) thumbnails.getLQThumbnail() else thumbnails.getHQThumbnail(); diff --git a/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt b/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt index 5c311c70..a3abc9ab 100644 --- a/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt +++ b/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt @@ -26,6 +26,7 @@ import android.util.Log import android.view.KeyEvent import androidx.core.app.NotificationCompat import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition import com.futo.platformplayer.R @@ -224,6 +225,7 @@ class MediaPlaybackService : Service() { val tag = video; Glide.with(this).asBitmap() .load(thumbnail) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .into(object: CustomTarget() { override fun onResourceReady(resource: Bitmap,transition: Transition?) { if (tag != _notif_last_video) return diff --git a/app/src/main/java/com/futo/platformplayer/states/StateNotifications.kt b/app/src/main/java/com/futo/platformplayer/states/StateNotifications.kt index e5f01a84..7e011eae 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateNotifications.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateNotifications.kt @@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable import android.os.Build import androidx.core.app.NotificationCompat import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition import com.futo.platformplayer.activities.MainActivity @@ -96,6 +97,7 @@ class StateNotifications { if(thumbnail != null) Glide.with(context).asBitmap() .load(thumbnail) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .into(object: CustomTarget() { override fun onResourceReady(resource: Bitmap, transition: Transition?) { notifyNewContent(context, manager, notificationChannel, id, content, resource); diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistsViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistsViewHolder.kt index e7fc852a..d6f0a001 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistsViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/PlaylistsViewHolder.kt @@ -7,6 +7,7 @@ import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.R import com.futo.platformplayer.constructs.Event0 import com.futo.platformplayer.images.GlideHelper.Companion.crossfade @@ -44,6 +45,7 @@ class PlaylistsViewHolder : ViewHolder { if (p.videos.isNotEmpty()) { Glide.with(_imageThumbnail) .load(p.videos[0].thumbnails.getMinimumThumbnail(380)) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .placeholder(R.drawable.placeholder_video_thumbnail) .crossfade() .into(_imageThumbnail); diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/VideoListEditorViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/VideoListEditorViewHolder.kt index 469ce702..1ece9278 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/VideoListEditorViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/VideoListEditorViewHolder.kt @@ -12,6 +12,7 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.R import com.futo.platformplayer.api.media.models.video.IPlatformVideo import com.futo.platformplayer.constructs.Event1 @@ -89,6 +90,7 @@ class VideoListEditorViewHolder : ViewHolder { fun bind(v: IPlatformVideo, canEdit: Boolean) { Glide.with(_imageThumbnail) .load(v.thumbnails.getHQThumbnail()) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .placeholder(R.drawable.placeholder_video_thumbnail) .crossfade() .into(_imageThumbnail); diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/LocalVideoTileViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/LocalVideoTileViewHolder.kt index 1adee422..2c32b32f 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/LocalVideoTileViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/LocalVideoTileViewHolder.kt @@ -7,6 +7,7 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.view.isVisible import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.R import com.futo.platformplayer.api.media.models.contents.IPlatformContent import com.futo.platformplayer.api.media.models.video.IPlatformVideo @@ -49,6 +50,7 @@ class LocalVideoTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHo Glide.with(it) .load(content.thumbnails.getHQThumbnail()) .placeholder(R.drawable.unknown_music) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .into(it) else Glide.with(it).load(R.drawable.unknown_music).into(it); diff --git a/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt b/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt index fe55714e..b8b67528 100644 --- a/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt @@ -18,6 +18,7 @@ import androidx.media3.common.util.UnstableApi import androidx.media3.ui.DefaultTimeBar import androidx.media3.ui.TimeBar import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.R import com.futo.platformplayer.Settings import com.futo.platformplayer.api.media.models.chapters.IChapter @@ -306,6 +307,7 @@ class CastView : ConstraintLayout { Glide.with(_thumbnail) .load(video.thumbnails.getHQThumbnail()) .placeholder(R.drawable.placeholder_video_thumbnail) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .into(_thumbnail); _textPosition.text = (position * 1000).formatDuration(); _textDuration.text = (video.duration * 1000).formatDuration(); diff --git a/app/src/main/java/com/futo/platformplayer/views/items/ActiveDownloadItem.kt b/app/src/main/java/com/futo/platformplayer/views/items/ActiveDownloadItem.kt index fa393dd9..af6cd6c0 100644 --- a/app/src/main/java/com/futo/platformplayer/views/items/ActiveDownloadItem.kt +++ b/app/src/main/java/com/futo/platformplayer/views/items/ActiveDownloadItem.kt @@ -6,6 +6,7 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.* import com.futo.platformplayer.downloads.VideoDownload import com.futo.platformplayer.images.GlideHelper.Companion.crossfade @@ -60,6 +61,7 @@ class ActiveDownloadItem: LinearLayout { } Glide.with(_videoImage) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .load(download.thumbnail) .crossfade() .into(_videoImage); diff --git a/app/src/main/java/com/futo/platformplayer/views/items/PlaylistDownloadItem.kt b/app/src/main/java/com/futo/platformplayer/views/items/PlaylistDownloadItem.kt index 8a5a43f2..df519035 100644 --- a/app/src/main/java/com/futo/platformplayer/views/items/PlaylistDownloadItem.kt +++ b/app/src/main/java/com/futo/platformplayer/views/items/PlaylistDownloadItem.kt @@ -5,6 +5,7 @@ import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.R import com.futo.platformplayer.images.GlideHelper.Companion.crossfade import com.futo.platformplayer.models.PlaylistDownloaded @@ -19,6 +20,7 @@ class PlaylistDownloadItem(context: Context, playlistName: String, playlistThumb imageText.text = playlistName; Glide.with(imageView) .load(playlistThumbnail) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .crossfade() .into(imageView); } diff --git a/app/src/main/java/com/futo/platformplayer/views/video/FutoThumbnailPlayer.kt b/app/src/main/java/com/futo/platformplayer/views/video/FutoThumbnailPlayer.kt index 80175ab8..400a4825 100644 --- a/app/src/main/java/com/futo/platformplayer/views/video/FutoThumbnailPlayer.kt +++ b/app/src/main/java/com/futo/platformplayer/views/video/FutoThumbnailPlayer.kt @@ -15,6 +15,7 @@ import androidx.media3.common.util.UnstableApi import androidx.media3.ui.PlayerControlView import androidx.media3.ui.PlayerView import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition import com.futo.platformplayer.R @@ -135,7 +136,7 @@ class FutoThumbnailPlayer : FutoVideoPlayerBase { if (videoSource == null && audioSource != null) { val thumbnail = video.thumbnails.getHQThumbnail(); if (!thumbnail.isNullOrBlank()) { - Glide.with(videoView).asBitmap().load(thumbnail).into(_loadArtwork); + Glide.with(videoView).asBitmap().load(thumbnail).downsample(DownsampleStrategy.AT_MOST).override(1080, 1080).into(_loadArtwork); } else { Glide.with(videoView).clear(_loadArtwork); setArtwork(null); diff --git a/app/src/main/java/com/futo/platformplayer/views/videometa/UpNextView.kt b/app/src/main/java/com/futo/platformplayer/views/videometa/UpNextView.kt index 26a908c6..5ba0c4bd 100644 --- a/app/src/main/java/com/futo/platformplayer/views/videometa/UpNextView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/videometa/UpNextView.kt @@ -11,6 +11,7 @@ import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.futo.platformplayer.states.StatePlayer import com.futo.platformplayer.R import com.futo.platformplayer.constructs.Event0 @@ -160,6 +161,7 @@ class UpNextView : LinearLayout { _textChannelName.text = nextItem.author.name; Glide.with(_imageThumbnail) .load(nextItem.thumbnails.getHQThumbnail()) + .downsample(DownsampleStrategy.AT_MOST).override(1080, 1080) .placeholder(R.drawable.placeholder_video_thumbnail) .into(_imageThumbnail); Glide.with(_imageChannelThumbnail)