[YouTube] Add utility methods to get images from InfoItems and thumbnails arrays

Unmodifiable lists of Images are returned, parsed from a given YouTube
"thumbnails" JSON array.

These methods will be used in all YouTube extractors and InfoItems, as the
structures between content types (videos, channels, playlists, ...) are common.
This commit is contained in:
AudricV 2022-07-22 17:28:39 +02:00
parent d56b880cae
commit adfad086ac
No known key found for this signature in database
GPG Key ID: DA92EC7905614198

View File

@ -33,6 +33,9 @@ import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException;
import com.grack.nanojson.JsonWriter;
import org.jsoup.nodes.Entities;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.Image.ResolutionLevel;
import org.schabi.newpipe.extractor.MetaInfo;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException;
@ -69,6 +72,7 @@ import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
@ -1133,17 +1137,61 @@ public final class YoutubeParsingHelper {
return result;
}
public static String getThumbnailUrlFromInfoItem(final JsonObject infoItem)
/**
* Get thumbnails from a {@link JsonObject} representing a YouTube
* {@link org.schabi.newpipe.extractor.InfoItem InfoItem}.
*
* <p>
* Thumbnails are got from the {@code thumbnails} {@link JsonArray} inside the {@code thumbnail}
* {@link JsonObject} of the YouTube {@link org.schabi.newpipe.extractor.InfoItem InfoItem},
* using {@link #getImagesFromThumbnailsArray(JsonArray)}.
* </p>
*
* @param infoItem a YouTube {@link org.schabi.newpipe.extractor.InfoItem InfoItem}
* @return an unmodifiable list of {@link Image}s found in the {@code thumbnails}
* {@link JsonArray}
* @throws ParsingException if an exception occurs when
* {@link #getImagesFromThumbnailsArray(JsonArray)} is executed
*/
@Nonnull
public static List<Image> getThumbnailsFromInfoItem(@Nonnull final JsonObject infoItem)
throws ParsingException {
// TODO: Don't simply get the first item, but look at all thumbnails and their resolution
try {
return fixThumbnailUrl(infoItem.getObject("thumbnail").getArray("thumbnails")
.getObject(0).getString("url"));
return getImagesFromThumbnailsArray(infoItem.getObject("thumbnail")
.getArray("thumbnails"));
} catch (final Exception e) {
throw new ParsingException("Could not get thumbnail url", e);
throw new ParsingException("Could not get thumbnails from InfoItem", e);
}
}
/**
* Get images from a YouTube {@code thumbnails} {@link JsonArray}.
*
* <p>
* The properties of the {@link Image}s created will be set using the corresponding ones of
* thumbnail items.
* </p>
*
* @param thumbnails a YouTube {@code thumbnails} {@link JsonArray}
* @return an unmodifiable list of {@link Image}s extracted from the given {@link JsonArray}
*/
@Nonnull
public static List<Image> getImagesFromThumbnailsArray(
@Nonnull final JsonArray thumbnails) {
return thumbnails.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.filter(thumbnail -> !isNullOrEmpty(thumbnail.getString("url")))
.map(thumbnail -> {
final int height = thumbnail.getInt("height", Image.HEIGHT_UNKNOWN);
return new Image(fixThumbnailUrl(thumbnail.getString("url")),
height,
thumbnail.getInt("width", Image.WIDTH_UNKNOWN),
ResolutionLevel.fromHeight(height));
})
.collect(Collectors.toUnmodifiableList());
}
@Nonnull
public static String getValidJsonResponseBody(@Nonnull final Response response)
throws ParsingException, MalformedURLException {