From ac00459c1a85c0581007e1bb9fc4fdd1a1e7d975 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Sat, 30 Sep 2023 21:11:09 +0200 Subject: [PATCH 1/2] Change requirement of image extensions in ImageSuffix class' Javadoc to a possibility Some services may provide different image formats using the same suffix, without we know what format the service provide. Enforcing an image extension could so lead to provide invalid image URLs, like for SoundCloud PNG images currently. With this documentation change, it is now clear that users of this class decide of whether they want to include image extensions in the suffix. The previous behavior described in the Javadoc was not enforced. --- .../org/schabi/newpipe/extractor/utils/ImageSuffix.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/ImageSuffix.java b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/ImageSuffix.java index d1ba7359c..4d8a14191 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/ImageSuffix.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/ImageSuffix.java @@ -7,9 +7,9 @@ import java.io.Serializable; import java.util.Objects; /** - * Serializable class representing a suffix (including its format extension, such as {@code .jpg}) - * which needs to be added to get an image/thumbnail URL with its corresponding height, width and - * estimated resolution level. + * Serializable class representing a suffix (which may include its format extension, such as + * {@code .jpg}) which needs to be added to get an image/thumbnail URL with its corresponding + * height, width and estimated resolution level. * *

* This class is used to construct {@link org.schabi.newpipe.extractor.Image Image} From c98695fceab35e9f73c3bdc1c9a01edf025aba40 Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Sat, 30 Sep 2023 21:11:53 +0200 Subject: [PATCH 2/2] [SoundCloud] Fix extraction of non-JPG images Default image qualities were removed in image URLs with the jpg extension, causing the addition of the image suffix to full non-JPG images URLs and so to invalid image URLs. Only the image quality name with its leading "-" character and the "." character after the name is now removed and replaced by a string format replaced itself with the image quality name for each quality. As the image suffixes do not contain the image extension, the name of image qualities lists has been adapted with these changes and some related comments have been also improved. --- .../soundcloud/SoundcloudParsingHelper.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java index bae7c4fe4..930d79f51 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java @@ -52,7 +52,7 @@ public final class SoundcloudParsingHelper { // and researches on images used by the websites // CHECKSTYLE:ON /* - SoundCloud avatars and artworks are almost squares + SoundCloud avatars and artworks are almost always squares. When we get non-square pictures, all these images variants are still squares, except the original and the crop versions provides images which are respecting aspect ratios. @@ -62,28 +62,28 @@ public final class SoundcloudParsingHelper { uploaded with a lower size than these variants: in this case, these variants return an upscaled version of the original image. */ - private static final List ALBUMS_AND_ARTWORKS_URL_SUFFIXES_AND_RESOLUTIONS = - List.of(new ImageSuffix("mini.jpg", 16, 16, LOW), - new ImageSuffix("t20x20.jpg", 20, 20, LOW), - new ImageSuffix("small.jpg", 32, 32, LOW), - new ImageSuffix("badge.jpg", 47, 47, LOW), - new ImageSuffix("t50x50.jpg", 50, 50, LOW), - new ImageSuffix("t60x60.jpg", 60, 60, LOW), + private static final List ALBUMS_AND_ARTWORKS_IMAGE_SUFFIXES = + List.of(new ImageSuffix("mini", 16, 16, LOW), + new ImageSuffix("t20x20", 20, 20, LOW), + new ImageSuffix("small", 32, 32, LOW), + new ImageSuffix("badge", 47, 47, LOW), + new ImageSuffix("t50x50", 50, 50, LOW), + new ImageSuffix("t60x60", 60, 60, LOW), // Seems to work also on avatars, even if it is written to be not the case in // the old API docs - new ImageSuffix("t67x67.jpg", 67, 67, LOW), - new ImageSuffix("t80x80.jpg", 80, 80, LOW), - new ImageSuffix("large.jpg", 100, 100, LOW), - new ImageSuffix("t120x120.jpg", 120, 120, LOW), - new ImageSuffix("t200x200.jpg", 200, 200, MEDIUM), - new ImageSuffix("t240x240.jpg", 240, 240, MEDIUM), - new ImageSuffix("t250x250.jpg", 250, 250, MEDIUM), - new ImageSuffix("t300x300.jpg", 300, 300, MEDIUM), - new ImageSuffix("t500x500.jpg", 500, 500, MEDIUM)); + new ImageSuffix("t67x67", 67, 67, LOW), + new ImageSuffix("t80x80", 80, 80, LOW), + new ImageSuffix("large", 100, 100, LOW), + new ImageSuffix("t120x120", 120, 120, LOW), + new ImageSuffix("t200x200", 200, 200, MEDIUM), + new ImageSuffix("t240x240", 240, 240, MEDIUM), + new ImageSuffix("t250x250", 250, 250, MEDIUM), + new ImageSuffix("t300x300", 300, 300, MEDIUM), + new ImageSuffix("t500x500", 500, 500, MEDIUM)); - private static final List VISUALS_URL_SUFFIXES_AND_RESOLUTIONS = - List.of(new ImageSuffix("t1240x260.jpg", 1240, 260, MEDIUM), - new ImageSuffix("t2480x520.jpg", 2480, 520, MEDIUM)); + private static final List VISUALS_IMAGE_SUFFIXES = + List.of(new ImageSuffix("t1240x260", 1240, 260, MEDIUM), + new ImageSuffix("t2480x520", 2480, 520, MEDIUM)); private static String clientId; public static final String SOUNDCLOUD_API_V2_URL = "https://api-v2.soundcloud.com/"; @@ -435,9 +435,9 @@ public final class SoundcloudParsingHelper { return getAllImagesFromImageUrlReturned( // Artwork and avatars are originally returned with the "large" resolution, which - // is 100x100 - originalArtworkOrAvatarUrl.replace("large.jpg", ""), - ALBUMS_AND_ARTWORKS_URL_SUFFIXES_AND_RESOLUTIONS); + // is 100px wide + originalArtworkOrAvatarUrl.replace("-large.", "-%s."), + ALBUMS_AND_ARTWORKS_IMAGE_SUFFIXES); } @Nonnull @@ -450,15 +450,16 @@ public final class SoundcloudParsingHelper { return getAllImagesFromImageUrlReturned( // Images are originally returned with the "original" resolution, which may be // huge so don't include it for size purposes - originalVisualUrl.replace("original.jpg", ""), - VISUALS_URL_SUFFIXES_AND_RESOLUTIONS); + originalVisualUrl.replace("-original.", "-%s."), + VISUALS_IMAGE_SUFFIXES); } private static List getAllImagesFromImageUrlReturned( - @Nonnull final String baseImageUrl, + @Nonnull final String baseImageUrlFormat, @Nonnull final List imageSuffixes) { return imageSuffixes.stream() - .map(imageSuffix -> new Image(baseImageUrl + imageSuffix.getSuffix(), + .map(imageSuffix -> new Image( + String.format(baseImageUrlFormat, imageSuffix.getSuffix()), imageSuffix.getHeight(), imageSuffix.getWidth(), imageSuffix.getResolutionLevel())) .collect(Collectors.toUnmodifiableList());