Support obtaining multiple images from the extractor

This commit is contained in:
Stypox 2023-05-01 23:11:48 +02:00
parent e2de83188a
commit af2375948d
No known key found for this signature in database
GPG key ID: 4BDF1B40A49FDD23
30 changed files with 190 additions and 77 deletions

View file

@ -1,13 +1,14 @@
package org.schabi.newpipe.util;
import static org.schabi.newpipe.MainActivity.DEBUG;
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
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;
@ -19,9 +20,13 @@ import com.squareup.picasso.RequestCreator;
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;
import okhttp3.OkHttpClient;
@ -42,6 +47,7 @@ public final class PicassoHelper {
private static Picasso picassoInstance;
private static boolean shouldLoadImages;
private static ResolutionLevel preferredResolutionLevel = ResolutionLevel.HIGH;
public static void init(final Context context) {
picassoCache = new LruCache(10 * 1024 * 1024);
@ -96,20 +102,33 @@ public final class PicassoHelper {
}
public static RequestCreator loadAvatar(final List<Image> images) {
return loadImageDefault(images, R.drawable.placeholder_person);
}
public static RequestCreator loadAvatar(final String url) {
return loadImageDefault(url, R.drawable.placeholder_person);
}
public static RequestCreator loadThumbnail(final List<Image> images) {
return loadImageDefault(images, R.drawable.placeholder_thumbnail_video);
}
public static RequestCreator loadThumbnail(final String url) {
return loadImageDefault(url, R.drawable.placeholder_thumbnail_video);
}
public static RequestCreator loadDetailsThumbnail(final String url) {
return loadImageDefault(url, R.drawable.placeholder_thumbnail_video, false);
public static RequestCreator loadDetailsThumbnail(final List<Image> images) {
return loadImageDefault(choosePreferredImage(images),
R.drawable.placeholder_thumbnail_video, false);
}
public static RequestCreator loadBanner(final String url) {
return loadImageDefault(url, R.drawable.placeholder_channel_banner);
public static RequestCreator loadBanner(final List<Image> images) {
return loadImageDefault(images, R.drawable.placeholder_channel_banner);
}
public static RequestCreator loadPlaylistThumbnail(final List<Image> images) {
return loadImageDefault(images, R.drawable.placeholder_thumbnail_playlist);
}
public static RequestCreator loadPlaylistThumbnail(final String url) {
@ -125,9 +144,10 @@ public final class PicassoHelper {
}
public static RequestCreator loadScaledDownThumbnail(final Context context, final String url) {
public static RequestCreator loadScaledDownThumbnail(final Context context,
final List<Image> images) {
// scale down the notification thumbnail for performance
return PicassoHelper.loadThumbnail(url)
return PicassoHelper.loadThumbnail(images)
.transform(new Transformation() {
@Override
public Bitmap transform(final Bitmap source) {
@ -180,13 +200,20 @@ public final class PicassoHelper {
}
private static RequestCreator loadImageDefault(final String url, final int placeholderResId) {
private static RequestCreator loadImageDefault(final List<Image> images,
final int placeholderResId) {
return loadImageDefault(choosePreferredImage(images), placeholderResId);
}
private static RequestCreator loadImageDefault(final String url,
final int placeholderResId) {
return loadImageDefault(url, placeholderResId, true);
}
private static RequestCreator loadImageDefault(final String url, final int placeholderResId,
private static RequestCreator loadImageDefault(@Nullable final String url,
final int placeholderResId,
final boolean showPlaceholderWhileLoading) {
if (!shouldLoadImages || isBlank(url)) {
if (isNullOrEmpty(url)) {
return picassoInstance
.load((String) null)
.placeholder(placeholderResId) // show placeholder when no image should load
@ -201,4 +228,44 @@ public final class PicassoHelper {
return requestCreator;
}
}
@Nullable
public static String choosePreferredImage(final List<Image> images) {
if (!shouldLoadImages) {
return null;
}
final Comparator<Image> comparator;
switch (preferredResolutionLevel) {
case HIGH:
comparator = Comparator.comparingInt(Image::getHeight).reversed();
break;
default:
case UNKNOWN:
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));
}
}
}

View file

@ -23,10 +23,12 @@ 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.PicassoHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
public final class ShareUtils {
private static final String TAG = ShareUtils.class.getSimpleName();
@ -261,6 +263,29 @@ public final class ShareUtils {
openAppChooser(context, shareIntent, false);
}
/**
* Open the android share sheet to share a content.
*
* <p>
* For Android 10+ users, a content preview is shown, which includes the title of the shared
* content and an image preview the content, if its URL is not null or empty and its
* corresponding image is in the image cache.
* </p>
*
* @param context the context to use
* @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
* 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));
}
/**
* Open the android share sheet to share a content.
*