mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 15:23:00 +00:00 
			
		
		
		
	Implement better image selection strategy
This commit is contained in:
		| @@ -20,6 +20,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader; | ||||
| import org.schabi.newpipe.ktx.ExceptionUtils; | ||||
| import org.schabi.newpipe.settings.NewPipeSettings; | ||||
| import org.schabi.newpipe.util.Localization; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.ServiceHelper; | ||||
| import org.schabi.newpipe.util.StateSaver; | ||||
| @@ -100,7 +101,7 @@ public class App extends Application { | ||||
|         // Initialize image loader | ||||
|         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); | ||||
|         PicassoHelper.init(this); | ||||
|         PicassoHelper.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, | ||||
|         ImageStrategy.setPreferredImageQuality(PreferredImageQuality.fromPreferenceKey(this, | ||||
|                 prefs.getString(getString(R.string.image_quality_key), | ||||
|                         getString(R.string.image_quality_default)))); | ||||
|         PicassoHelper.setIndicatorsEnabled(MainActivity.DEBUG | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity | ||||
| import org.schabi.newpipe.database.stream.model.StreamEntity | ||||
| import org.schabi.newpipe.database.stream.model.StreamStateEntity | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfoItem | ||||
| import org.schabi.newpipe.util.image.PicassoHelper | ||||
| import org.schabi.newpipe.util.image.ImageStrategy | ||||
|  | ||||
| data class PlaylistStreamEntry( | ||||
|     @Embedded | ||||
| @@ -29,7 +29,7 @@ data class PlaylistStreamEntry( | ||||
|         item.duration = streamEntity.duration | ||||
|         item.uploaderName = streamEntity.uploader | ||||
|         item.uploaderUrl = streamEntity.uploaderUrl | ||||
|         item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) | ||||
|         item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) | ||||
|  | ||||
|         return item | ||||
|     } | ||||
|   | ||||
| @@ -11,7 +11,7 @@ import androidx.room.PrimaryKey; | ||||
| import org.schabi.newpipe.database.playlist.PlaylistLocalItem; | ||||
| import org.schabi.newpipe.extractor.playlist.PlaylistInfo; | ||||
| import org.schabi.newpipe.util.Constants; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import static org.schabi.newpipe.database.LocalItem.LocalItemType.PLAYLIST_REMOTE_ITEM; | ||||
| import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_NAME; | ||||
| @@ -70,7 +70,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { | ||||
|     @Ignore | ||||
|     public PlaylistRemoteEntity(final PlaylistInfo info) { | ||||
|         this(info.getServiceId(), info.getName(), info.getUrl(), | ||||
|                 PicassoHelper.choosePreferredImage(info.getThumbnails()), | ||||
|                 ImageStrategy.choosePreferredImage(info.getThumbnails()), | ||||
|                 info.getUploaderName(), info.getStreamCount()); | ||||
|     } | ||||
|  | ||||
| @@ -85,7 +85,7 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { | ||||
|                 && TextUtils.equals(getName(), info.getName()) | ||||
|                 && TextUtils.equals(getUrl(), info.getUrl()) | ||||
|                 && TextUtils.equals(getThumbnailUrl(), | ||||
|                 PicassoHelper.choosePreferredImage(info.getThumbnails())) | ||||
|                 ImageStrategy.choosePreferredImage(info.getThumbnails())) | ||||
|                 && TextUtils.equals(getUploader(), info.getUploaderName()); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import org.schabi.newpipe.database.history.model.StreamHistoryEntity | ||||
| import org.schabi.newpipe.database.stream.model.StreamEntity | ||||
| import org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfoItem | ||||
| import org.schabi.newpipe.util.image.PicassoHelper | ||||
| import org.schabi.newpipe.util.image.ImageStrategy | ||||
| import java.time.OffsetDateTime | ||||
|  | ||||
| class StreamStatisticsEntry( | ||||
| @@ -31,7 +31,7 @@ class StreamStatisticsEntry( | ||||
|         item.duration = streamEntity.duration | ||||
|         item.uploaderName = streamEntity.uploader | ||||
|         item.uploaderUrl = streamEntity.uploaderUrl | ||||
|         item.thumbnails = PicassoHelper.urlToImageList(streamEntity.thumbnailUrl) | ||||
|         item.thumbnails = ImageStrategy.urlToImageList(streamEntity.thumbnailUrl) | ||||
|  | ||||
|         return item | ||||
|     } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfoItem | ||||
| import org.schabi.newpipe.extractor.stream.StreamType | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueueItem | ||||
| import org.schabi.newpipe.util.image.PicassoHelper | ||||
| import org.schabi.newpipe.util.image.ImageStrategy | ||||
| import java.io.Serializable | ||||
| import java.time.OffsetDateTime | ||||
|  | ||||
| @@ -68,7 +68,7 @@ data class StreamEntity( | ||||
|     constructor(item: StreamInfoItem) : this( | ||||
|         serviceId = item.serviceId, url = item.url, title = item.name, | ||||
|         streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, | ||||
|         uploaderUrl = item.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, | ||||
|         uploaderUrl = item.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails), viewCount = item.viewCount, | ||||
|         textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), | ||||
|         isUploadDateApproximation = item.uploadDate?.isApproximation | ||||
|     ) | ||||
| @@ -77,7 +77,7 @@ data class StreamEntity( | ||||
|     constructor(info: StreamInfo) : this( | ||||
|         serviceId = info.serviceId, url = info.url, title = info.name, | ||||
|         streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, | ||||
|         uploaderUrl = info.uploaderUrl, thumbnailUrl = PicassoHelper.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, | ||||
|         uploaderUrl = info.uploaderUrl, thumbnailUrl = ImageStrategy.choosePreferredImage(info.thumbnails), viewCount = info.viewCount, | ||||
|         textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), | ||||
|         isUploadDateApproximation = info.uploadDate?.isApproximation | ||||
|     ) | ||||
| @@ -87,7 +87,7 @@ data class StreamEntity( | ||||
|         serviceId = item.serviceId, url = item.url, title = item.title, | ||||
|         streamType = item.streamType, duration = item.duration, uploader = item.uploader, | ||||
|         uploaderUrl = item.uploaderUrl, | ||||
|         thumbnailUrl = PicassoHelper.choosePreferredImage(item.thumbnails) | ||||
|         thumbnailUrl = ImageStrategy.choosePreferredImage(item.thumbnails) | ||||
|     ) | ||||
|  | ||||
|     fun toStreamInfoItem(): StreamInfoItem { | ||||
| @@ -95,7 +95,7 @@ data class StreamEntity( | ||||
|         item.duration = duration | ||||
|         item.uploaderName = uploader | ||||
|         item.uploaderUrl = uploaderUrl | ||||
|         item.thumbnails = PicassoHelper.urlToImageList(thumbnailUrl) | ||||
|         item.thumbnails = ImageStrategy.urlToImageList(thumbnailUrl) | ||||
|  | ||||
|         if (viewCount != null) item.viewCount = viewCount as Long | ||||
|         item.textualUploadDate = textualUploadDate | ||||
|   | ||||
| @@ -10,7 +10,7 @@ import androidx.room.PrimaryKey; | ||||
| import org.schabi.newpipe.extractor.channel.ChannelInfo; | ||||
| import org.schabi.newpipe.extractor.channel.ChannelInfoItem; | ||||
| import org.schabi.newpipe.util.Constants; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_SERVICE_ID; | ||||
| import static org.schabi.newpipe.database.subscription.SubscriptionEntity.SUBSCRIPTION_TABLE; | ||||
| @@ -58,7 +58,7 @@ public class SubscriptionEntity { | ||||
|         final SubscriptionEntity result = new SubscriptionEntity(); | ||||
|         result.setServiceId(info.getServiceId()); | ||||
|         result.setUrl(info.getUrl()); | ||||
|         result.setData(info.getName(), PicassoHelper.choosePreferredImage(info.getAvatars()), | ||||
|         result.setData(info.getName(), ImageStrategy.choosePreferredImage(info.getAvatars()), | ||||
|                 info.getDescription(), info.getSubscriberCount()); | ||||
|         return result; | ||||
|     } | ||||
| @@ -139,7 +139,7 @@ public class SubscriptionEntity { | ||||
|     @Ignore | ||||
|     public ChannelInfoItem toChannelInfoItem() { | ||||
|         final ChannelInfoItem item = new ChannelInfoItem(getServiceId(), getUrl(), getName()); | ||||
|         item.setThumbnails(PicassoHelper.urlToImageList(getAvatarUrl())); | ||||
|         item.setThumbnails(ImageStrategy.urlToImageList(getAvatarUrl())); | ||||
|         item.setSubscriberCount(getSubscriberCount()); | ||||
|         item.setDescription(getDescription()); | ||||
|         return item; | ||||
|   | ||||
| @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfo; | ||||
| import org.schabi.newpipe.util.Localization; | ||||
|  | ||||
| import java.util.List; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import icepick.State; | ||||
|  | ||||
| @@ -114,7 +114,7 @@ public class DescriptionFragment extends BaseDescriptionFragment { | ||||
|         addMetadataItem(inflater, layout, true, R.string.metadata_host, | ||||
|                 streamInfo.getHost()); | ||||
|         addMetadataItem(inflater, layout, true, R.string.metadata_thumbnail_url, | ||||
|                 PicassoHelper.choosePreferredImage(streamInfo.getThumbnails())); | ||||
|                 ImageStrategy.choosePreferredImage(streamInfo.getThumbnails())); | ||||
|     } | ||||
|  | ||||
|     private void addPrivacyMetadataItem(final LayoutInflater inflater, final LinearLayout layout) { | ||||
|   | ||||
| @@ -17,7 +17,7 @@ import org.schabi.newpipe.extractor.stream.Description; | ||||
| import org.schabi.newpipe.fragments.detail.BaseDescriptionFragment; | ||||
| import org.schabi.newpipe.util.DeviceUtils; | ||||
| import org.schabi.newpipe.util.Localization; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -101,8 +101,8 @@ public class ChannelAboutFragment extends BaseDescriptionFragment { | ||||
|         } | ||||
|  | ||||
|         addMetadataItem(inflater, layout, true, R.string.metadata_avatar_url, | ||||
|                 PicassoHelper.choosePreferredImage(channelInfo.getAvatars())); | ||||
|                 ImageStrategy.choosePreferredImage(channelInfo.getAvatars())); | ||||
|         addMetadataItem(inflater, layout, true, R.string.metadata_banner_url, | ||||
|                 PicassoHelper.choosePreferredImage(channelInfo.getBanners())); | ||||
|                 ImageStrategy.choosePreferredImage(channelInfo.getBanners())); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -49,6 +49,7 @@ import org.schabi.newpipe.util.ExtractorHelper; | ||||
| import org.schabi.newpipe.util.Localization; | ||||
| import org.schabi.newpipe.util.NavigationHelper; | ||||
| import org.schabi.newpipe.util.StateSaver; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.ThemeHelper; | ||||
| import org.schabi.newpipe.util.external_communication.ShareUtils; | ||||
| @@ -147,7 +148,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo> | ||||
|  | ||||
|         setTitle(name); | ||||
|         binding.channelTitleView.setText(name); | ||||
|         if (!PicassoHelper.shouldLoadImages()) { | ||||
|         if (!ImageStrategy.shouldLoadImages()) { | ||||
|             // do not waste space for the banner if it is not going to be loaded | ||||
|             binding.channelBannerImage.setImageDrawable(null); | ||||
|         } | ||||
| @@ -354,7 +355,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo> | ||||
|                 channel.setServiceId(info.getServiceId()); | ||||
|                 channel.setUrl(info.getUrl()); | ||||
|                 channel.setData(info.getName(), | ||||
|                         PicassoHelper.choosePreferredImage(info.getAvatars()), | ||||
|                         ImageStrategy.choosePreferredImage(info.getAvatars()), | ||||
|                         info.getDescription(), | ||||
|                         info.getSubscriberCount()); | ||||
|                 channelSubscription = null; | ||||
| @@ -578,7 +579,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo> | ||||
|         currentInfo = result; | ||||
|         setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName()); | ||||
|  | ||||
|         if (PicassoHelper.shouldLoadImages() && !result.getBanners().isEmpty()) { | ||||
|         if (ImageStrategy.shouldLoadImages() && !result.getBanners().isEmpty()) { | ||||
|             PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG) | ||||
|                     .into(binding.channelBannerImage); | ||||
|         } else { | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import org.schabi.newpipe.local.history.HistoryRecordManager; | ||||
| import org.schabi.newpipe.util.DeviceUtils; | ||||
| import org.schabi.newpipe.util.Localization; | ||||
| import org.schabi.newpipe.util.NavigationHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.external_communication.ShareUtils; | ||||
| import org.schabi.newpipe.util.text.CommentTextOnTouchListener; | ||||
| @@ -98,7 +99,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder { | ||||
|         final CommentsInfoItem item = (CommentsInfoItem) infoItem; | ||||
|  | ||||
|         PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView); | ||||
|         if (PicassoHelper.shouldLoadImages()) { | ||||
|         if (ImageStrategy.shouldLoadImages()) { | ||||
|             itemThumbnailView.setVisibility(View.VISIBLE); | ||||
|             itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding, | ||||
|                     commentVerticalPadding, commentVerticalPadding); | ||||
|   | ||||
| @@ -61,7 +61,7 @@ import org.schabi.newpipe.util.OnClickGesture | ||||
| import org.schabi.newpipe.util.ServiceHelper | ||||
| import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels | ||||
| import org.schabi.newpipe.util.external_communication.ShareUtils | ||||
| import org.schabi.newpipe.util.image.PicassoHelper | ||||
| import org.schabi.newpipe.util.image.ImageStrategy | ||||
| import java.text.SimpleDateFormat | ||||
| import java.util.Date | ||||
| import java.util.Locale | ||||
| @@ -343,7 +343,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() { | ||||
|             when (i) { | ||||
|                 0 -> ShareUtils.shareText( | ||||
|                     requireContext(), selectedItem.name, selectedItem.url, | ||||
|                     PicassoHelper.choosePreferredImage(selectedItem.thumbnails) | ||||
|                     ImageStrategy.choosePreferredImage(selectedItem.thumbnails) | ||||
|                 ) | ||||
|                 1 -> ShareUtils.openUrlInBrowser(requireContext(), selectedItem.url) | ||||
|                 2 -> deleteChannel(selectedItem) | ||||
|   | ||||
| @@ -19,7 +19,7 @@ import org.schabi.newpipe.extractor.feed.FeedInfo | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfoItem | ||||
| import org.schabi.newpipe.local.feed.FeedDatabaseManager | ||||
| import org.schabi.newpipe.util.ExtractorHelper | ||||
| import org.schabi.newpipe.util.image.PicassoHelper | ||||
| import org.schabi.newpipe.util.image.ImageStrategy | ||||
|  | ||||
| class SubscriptionManager(context: Context) { | ||||
|     private val database = NewPipeDatabase.getInstance(context) | ||||
| @@ -74,7 +74,7 @@ class SubscriptionManager(context: Context) { | ||||
|                 Completable.fromRunnable { | ||||
|                     it.setData( | ||||
|                         info.name, | ||||
|                         PicassoHelper.choosePreferredImage(info.avatars), | ||||
|                         ImageStrategy.choosePreferredImage(info.avatars), | ||||
|                         info.description, | ||||
|                         info.subscriberCount | ||||
|                     ) | ||||
| @@ -105,7 +105,7 @@ class SubscriptionManager(context: Context) { | ||||
|         } else if (info is ChannelInfo) { | ||||
|             subscriptionEntity.setData( | ||||
|                 info.name, | ||||
|                 PicassoHelper.choosePreferredImage(info.avatars), | ||||
|                 ImageStrategy.choosePreferredImage(info.avatars), | ||||
|                 info.description, | ||||
|                 info.subscriberCount | ||||
|             ) | ||||
|   | ||||
| @@ -3,7 +3,7 @@ package org.schabi.newpipe.player.mediaitem; | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfo; | ||||
| import org.schabi.newpipe.extractor.stream.StreamType; | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueueItem; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
| @@ -75,7 +75,7 @@ public final class ExceptionTag implements MediaItemTag { | ||||
|  | ||||
|     @Override | ||||
|     public String getThumbnailUrl() { | ||||
|         return PicassoHelper.choosePreferredImage(item.getThumbnails()); | ||||
|         return ImageStrategy.choosePreferredImage(item.getThumbnails()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import org.schabi.newpipe.extractor.stream.AudioStream; | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfo; | ||||
| import org.schabi.newpipe.extractor.stream.StreamType; | ||||
| import org.schabi.newpipe.extractor.stream.VideoStream; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| @@ -96,7 +96,7 @@ public final class StreamInfoTag implements MediaItemTag { | ||||
|  | ||||
|     @Override | ||||
|     public String getThumbnailUrl() { | ||||
|         return PicassoHelper.choosePreferredImage(streamInfo.getThumbnails()); | ||||
|         return ImageStrategy.choosePreferredImage(streamInfo.getThumbnails()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -20,7 +20,7 @@ import com.google.android.exoplayer2.util.Util; | ||||
| import org.schabi.newpipe.player.Player; | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueue; | ||||
| import org.schabi.newpipe.player.playqueue.PlayQueueItem; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| @@ -139,7 +139,7 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator | ||||
|         descBuilder.setExtras(additionalMetadata); | ||||
|  | ||||
|         final Uri thumbnailUri = Uri.parse( | ||||
|                 PicassoHelper.choosePreferredImage(item.getThumbnails())); | ||||
|                 ImageStrategy.choosePreferredImage(item.getThumbnails())); | ||||
|         if (thumbnailUri != null) { | ||||
|             descBuilder.setIconUri(thumbnailUri); | ||||
|         } | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import org.schabi.newpipe.extractor.localization.Localization; | ||||
| import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; | ||||
| import org.schabi.newpipe.streams.io.StoredFileHelper; | ||||
| import org.schabi.newpipe.util.NavigationHelper; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
| import org.schabi.newpipe.util.ZipHelper; | ||||
| import org.schabi.newpipe.util.image.PreferredImageQuality; | ||||
| @@ -109,7 +110,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { | ||||
|         final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); | ||||
|         imageQualityPreference.setOnPreferenceChangeListener( | ||||
|                 (preference, newValue) -> { | ||||
|                     PicassoHelper.setPreferredImageQuality(PreferredImageQuality | ||||
|                     ImageStrategy.setPreferredImageQuality(PreferredImageQuality | ||||
|                             .fromPreferenceKey(requireContext(), (String) newValue)); | ||||
|                     try { | ||||
|                         PicassoHelper.clearCache(preference.getContext()); | ||||
|   | ||||
| @@ -24,6 +24,7 @@ import androidx.core.content.FileProvider; | ||||
| import org.schabi.newpipe.BuildConfig; | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.extractor.Image; | ||||
| import org.schabi.newpipe.util.image.ImageStrategy; | ||||
| import org.schabi.newpipe.util.image.PicassoHelper; | ||||
|  | ||||
| import java.io.File; | ||||
| @@ -251,7 +252,7 @@ public final class ShareUtils { | ||||
|         // If loading of images has been disabled, don't try to generate a content preview | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q | ||||
|                 && !TextUtils.isEmpty(imagePreviewUrl) | ||||
|                 && PicassoHelper.shouldLoadImages()) { | ||||
|                 && ImageStrategy.shouldLoadImages()) { | ||||
|  | ||||
|             final ClipData clipData = generateClipDataForImagePreview(context, imagePreviewUrl); | ||||
|             if (clipData != null) { | ||||
| @@ -276,14 +277,14 @@ public final class ShareUtils { | ||||
|      * @param title   the title of the content | ||||
|      * @param content the content to share | ||||
|      * @param images  a set of possible {@link Image}s of the subject, among which to choose with | ||||
|      *                {@link PicassoHelper#choosePreferredImage(List)} since that's likely to | ||||
|      *                {@link ImageStrategy#choosePreferredImage(List)} since that's likely to | ||||
|      *                provide an image that is in Picasso's cache | ||||
|      */ | ||||
|     public static void shareText(@NonNull final Context context, | ||||
|                                  @NonNull final String title, | ||||
|                                  final String content, | ||||
|                                  final List<Image> images) { | ||||
|         shareText(context, title, content, PicassoHelper.choosePreferredImage(images)); | ||||
|         shareText(context, title, content, ImageStrategy.choosePreferredImage(images)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -0,0 +1,115 @@ | ||||
| package org.schabi.newpipe.util.image; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
|  | ||||
| import org.schabi.newpipe.extractor.Image; | ||||
|  | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
|  | ||||
| public final class ImageStrategy { | ||||
|  | ||||
|     // the height thresholds also used by the extractor (TODO move them to the extractor) | ||||
|     private static final int LOW_MEDIUM = 175; | ||||
|     private static final int MEDIUM_HIGH = 720; | ||||
|  | ||||
|     private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; | ||||
|  | ||||
|     private ImageStrategy() { | ||||
|     } | ||||
|  | ||||
|     public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { | ||||
|         ImageStrategy.preferredImageQuality = preferredImageQuality; | ||||
|     } | ||||
|  | ||||
|     public static boolean shouldLoadImages() { | ||||
|         return preferredImageQuality != PreferredImageQuality.NONE; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private static double estimatePixelCount(final Image image, | ||||
|                                              final double widthOverHeight, | ||||
|                                              final boolean unknownsLast) { | ||||
|         if (image.getHeight() == Image.HEIGHT_UNKNOWN) { | ||||
|             if (image.getWidth() == Image.WIDTH_UNKNOWN) { | ||||
|                 switch (image.getEstimatedResolutionLevel()) { | ||||
|                     case LOW: | ||||
|                         return unknownsLast | ||||
|                                 ? (LOW_MEDIUM - 1) * (LOW_MEDIUM - 1) * widthOverHeight | ||||
|                                 : 0; | ||||
|                     case MEDIUM: | ||||
|                         return unknownsLast | ||||
|                                 ? (MEDIUM_HIGH - 1) * (MEDIUM_HIGH - 1) * widthOverHeight | ||||
|                                 : LOW_MEDIUM * LOW_MEDIUM * widthOverHeight; | ||||
|                     case HIGH: | ||||
|                         return unknownsLast | ||||
|                                 ? 1e20 // less than 1e21 to prefer over fully unknown image sizes | ||||
|                                 : MEDIUM_HIGH * MEDIUM_HIGH * widthOverHeight; | ||||
|                     default: | ||||
|                     case UNKNOWN: | ||||
|                         // images whose size is completely unknown will be avoided when possible | ||||
|                         return unknownsLast ? 1e21 : -1; | ||||
|                 } | ||||
|  | ||||
|             } else { | ||||
|                 return image.getWidth() * image.getWidth() / widthOverHeight; | ||||
|             } | ||||
|  | ||||
|         } else if (image.getWidth() == Image.WIDTH_UNKNOWN) { | ||||
|             return image.getHeight() * image.getHeight() * widthOverHeight; | ||||
|  | ||||
|         } else { | ||||
|             return image.getHeight() * image.getWidth(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Nullable | ||||
|     public static String choosePreferredImage(@NonNull final List<Image> images) { | ||||
|         if (preferredImageQuality == PreferredImageQuality.NONE) { | ||||
|             return null; // do not load images | ||||
|         } | ||||
|  | ||||
|         final double widthOverHeight = images.stream() | ||||
|                 .filter(image -> image.getHeight() != Image.HEIGHT_UNKNOWN | ||||
|                         && image.getWidth() != Image.WIDTH_UNKNOWN) | ||||
|                 .mapToDouble(image -> ((double) image.getWidth()) / image.getHeight()) | ||||
|                 .findFirst() | ||||
|                 .orElse(1.0); | ||||
|  | ||||
|         final Comparator<Image> comparator; | ||||
|         switch (preferredImageQuality) { | ||||
|             case LOW: | ||||
|                 comparator = Comparator.comparingDouble( | ||||
|                         image -> estimatePixelCount(image, widthOverHeight, true)); | ||||
|                 break; | ||||
|             default: | ||||
|             case MEDIUM: | ||||
|                 comparator = Comparator.comparingDouble(image -> { | ||||
|                     final double pixelCount = estimatePixelCount(image, widthOverHeight, true); | ||||
|                     final double mediumHeight = (LOW_MEDIUM + MEDIUM_HIGH) / 2.0; | ||||
|                     return Math.abs(pixelCount - mediumHeight * mediumHeight * widthOverHeight); | ||||
|                 }); | ||||
|                 break; | ||||
|             case HIGH: | ||||
|                 comparator = Comparator.<Image>comparingDouble( | ||||
|                         image -> estimatePixelCount(image, widthOverHeight, false)) | ||||
|                         .reversed(); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return images.stream() | ||||
|                 .min(comparator) | ||||
|                 .map(Image::getUrl) | ||||
|                 .orElse(null); | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     public static List<Image> urlToImageList(@Nullable final String url) { | ||||
|         if (url == null) { | ||||
|             return List.of(); | ||||
|         } else { | ||||
|             return List.of(new Image(url, -1, -1, Image.ResolutionLevel.UNKNOWN)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -2,13 +2,13 @@ package org.schabi.newpipe.util.image; | ||||
|  | ||||
| import static org.schabi.newpipe.MainActivity.DEBUG; | ||||
| import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; | ||||
| import static org.schabi.newpipe.util.image.ImageStrategy.choosePreferredImage; | ||||
|  | ||||
| import android.annotation.SuppressLint; | ||||
| import android.content.Context; | ||||
| import android.graphics.Bitmap; | ||||
| import android.util.Log; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.core.graphics.BitmapCompat; | ||||
|  | ||||
| @@ -21,11 +21,9 @@ import com.squareup.picasso.Transformation; | ||||
|  | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.extractor.Image; | ||||
| import org.schabi.newpipe.extractor.Image.ResolutionLevel; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| @@ -46,7 +44,6 @@ public final class PicassoHelper { | ||||
|     @SuppressLint("StaticFieldLeak") | ||||
|     private static Picasso picassoInstance; | ||||
|  | ||||
|     private static PreferredImageQuality preferredImageQuality = PreferredImageQuality.MEDIUM; | ||||
|  | ||||
|     public static void init(final Context context) { | ||||
|         picassoCache = new LruCache(10 * 1024 * 1024); | ||||
| @@ -92,14 +89,6 @@ public final class PicassoHelper { | ||||
|         picassoInstance.setIndicatorsEnabled(enabled); // useful for debugging | ||||
|     } | ||||
|  | ||||
|     public static void setPreferredImageQuality(final PreferredImageQuality preferredImageQuality) { | ||||
|         PicassoHelper.preferredImageQuality = preferredImageQuality; | ||||
|     } | ||||
|  | ||||
|     public static boolean shouldLoadImages() { | ||||
|         return preferredImageQuality != PreferredImageQuality.NONE; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public static RequestCreator loadAvatar(final List<Image> images) { | ||||
|         return loadImageDefault(images, R.drawable.placeholder_person); | ||||
| @@ -227,41 +216,4 @@ public final class PicassoHelper { | ||||
|             return requestCreator; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Nullable | ||||
|     public static String choosePreferredImage(final List<Image> images) { | ||||
|         final Comparator<Image> comparator; | ||||
|         switch (preferredImageQuality) { | ||||
|             case NONE: | ||||
|                 return null; | ||||
|             case HIGH: | ||||
|                 comparator = Comparator.comparingInt(Image::getHeight).reversed(); | ||||
|                 break; | ||||
|             default: | ||||
|             case MEDIUM: | ||||
|                 comparator = Comparator.comparingInt(image -> Math.abs(image.getHeight() - 450)); | ||||
|                 break; | ||||
|             case LOW: | ||||
|                 comparator = Comparator.comparingInt(Image::getHeight); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return images.stream() | ||||
|                 .filter(image -> image.getEstimatedResolutionLevel() != ResolutionLevel.UNKNOWN) | ||||
|                 .min(comparator) | ||||
|                 .map(Image::getUrl) | ||||
|                 .orElseGet(() -> images.stream() | ||||
|                         .findAny() | ||||
|                         .map(Image::getUrl) | ||||
|                         .orElse(null)); | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     public static List<Image> urlToImageList(@Nullable final String url) { | ||||
|         if (url == null) { | ||||
|             return List.of(); | ||||
|         } else { | ||||
|             return List.of(new Image(url, -1, -1, ResolutionLevel.UNKNOWN)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox