diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamInfoItemExtractor.java index c823621de..db4041ee4 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamInfoItemExtractor.java @@ -1,13 +1,7 @@ package org.schabi.newpipe.extractor.services.youtube.extractors; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailUrlFromInfoItem; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromNavigationEndpoint; -import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; - import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonObject; - import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.localization.TimeAgoParser; @@ -18,12 +12,16 @@ import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Utils; +import javax.annotation.Nullable; import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; -import javax.annotation.Nullable; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailUrlFromInfoItem; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromNavigationEndpoint; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; /* * Copyright (C) Christian Schabesberger 2016 @@ -331,7 +329,37 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor { final String webPageType = videoInfo.getObject("navigationEndpoint") .getObject("commandMetadata").getObject("webCommandMetadata") .getString("webPageType"); - return !isNullOrEmpty(webPageType) && webPageType.equals("WEB_PAGE_TYPE_SHORTS"); + + boolean isShort = !isNullOrEmpty(webPageType) + && webPageType.equals("WEB_PAGE_TYPE_SHORTS"); + + if (!isShort) { + isShort = videoInfo.getObject("navigationEndpoint").has("reelWatchEndpoint"); + } + + if (!isShort) { + final JsonObject thumbnailTimeOverlay = videoInfo.getArray("thumbnailOverlays") + .stream() + .filter(JsonObject.class::isInstance) + .map(JsonObject.class::cast) + .filter(thumbnailOverlay -> thumbnailOverlay.has( + "thumbnailOverlayTimeStatusRenderer")) + .map(thumbnailOverlay -> thumbnailOverlay.getObject( + "thumbnailOverlayTimeStatusRenderer")) + .findFirst() + .orElse(null); + + if (!isNullOrEmpty(thumbnailTimeOverlay)) { + isShort = thumbnailTimeOverlay.getString("style") + .equalsIgnoreCase("SHORTS") + || thumbnailTimeOverlay.getObject("icon") + .getString("iconType") + .toLowerCase() + .contains("shorts"); + } + } + + return isShort; } catch (final Exception e) { throw new ParsingException("Could not determine if this is short-form content", e); } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java index 04117c38a..37adb475f 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItem.java @@ -139,7 +139,6 @@ public class StreamInfoItem extends InfoItem { this.shortFormContent = shortFormContent; } - @Override public String toString() { return "StreamInfoItem{" diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemExtractor.java index e70e6cc7e..27eb3066f 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfoItemExtractor.java @@ -129,10 +129,13 @@ public interface StreamInfoItemExtractor extends InfoItemExtractor { } /** - * Check if the stream is a short-form content + * Whether the stream is a short-form content. * - * @return {@code true} if the stream is a short-form content - * @throws ParsingException thrown if there is an error in the extraction + *

+ * Short-form contents are contents in the style of TikTok, YouTube Shorts, or Instagram Reels videos. + *

+ * + * @return whether the stream is a short-form content */ default boolean isShortFormContent() throws ParsingException { return false;