Merge pull request #1140 from Stypox/yt-shorts-no-duration

[YouTube] Always return -1 as duration of Shorts returned inside reel items
This commit is contained in:
Stypox 2023-12-21 21:52:40 +01:00 committed by GitHub
commit fc54fb2fdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 124 additions and 142 deletions

View File

@ -300,7 +300,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
getCommitVideoConsumer(collector, timeAgoParser, channelIds, getCommitVideoConsumer(collector, timeAgoParser, channelIds,
richItem.getObject("videoRenderer")); richItem.getObject("videoRenderer"));
} else if (richItem.has("reelItemRenderer")) { } else if (richItem.has("reelItemRenderer")) {
getCommitReelItemConsumer(collector, timeAgoParser, channelIds, getCommitReelItemConsumer(collector, channelIds,
richItem.getObject("reelItemRenderer")); richItem.getObject("reelItemRenderer"));
} else if (richItem.has("playlistRenderer")) { } else if (richItem.has("playlistRenderer")) {
getCommitPlaylistConsumer(collector, channelIds, getCommitPlaylistConsumer(collector, channelIds,
@ -356,11 +356,10 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
} }
private void getCommitReelItemConsumer(@Nonnull final MultiInfoItemsCollector collector, private void getCommitReelItemConsumer(@Nonnull final MultiInfoItemsCollector collector,
@Nonnull final TimeAgoParser timeAgoParser,
@Nonnull final List<String> channelIds, @Nonnull final List<String> channelIds,
@Nonnull final JsonObject jsonObject) { @Nonnull final JsonObject jsonObject) {
collector.commit( collector.commit(
new YoutubeReelInfoItemExtractor(jsonObject, timeAgoParser) { new YoutubeReelInfoItemExtractor(jsonObject) {
@Override @Override
public String getUploaderName() throws ParsingException { public String getUploaderName() throws ParsingException {
if (channelIds.size() >= 2) { if (channelIds.size() >= 2) {

View File

@ -411,8 +411,7 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
richItemRenderer.getObject("content"); richItemRenderer.getObject("content");
if (richItemRendererContent.has(REEL_ITEM_RENDERER)) { if (richItemRendererContent.has(REEL_ITEM_RENDERER)) {
collector.commit(new YoutubeReelInfoItemExtractor( collector.commit(new YoutubeReelInfoItemExtractor(
richItemRendererContent.getObject(REEL_ITEM_RENDERER), richItemRendererContent.getObject(REEL_ITEM_RENDERER)));
timeAgoParser));
} }
} }
} }

View File

@ -1,25 +1,24 @@
package org.schabi.newpipe.extractor.services.youtube.extractors; 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.getThumbnailsFromInfoItem;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.localization.TimeAgoParser;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailsFromInfoItem;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import java.util.List;
/** /**
* A {@link StreamInfoItemExtractor} for YouTube's {@code reelItemRenderers}. * A {@link StreamInfoItemExtractor} for YouTube's {@code reelItemRenderers}.
* *
@ -33,13 +32,9 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
@Nonnull @Nonnull
private final JsonObject reelInfo; private final JsonObject reelInfo;
@Nullable
private final TimeAgoParser timeAgoParser;
public YoutubeReelInfoItemExtractor(@Nonnull final JsonObject reelInfo, public YoutubeReelInfoItemExtractor(@Nonnull final JsonObject reelInfo) {
@Nullable final TimeAgoParser timeAgoParser) {
this.reelInfo = reelInfo; this.reelInfo = reelInfo;
this.timeAgoParser = timeAgoParser;
} }
@Override @Override
@ -68,28 +63,6 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
return StreamType.VIDEO_STREAM; return StreamType.VIDEO_STREAM;
} }
@Override
public long getDuration() throws ParsingException {
// Duration of reelItems is only provided in the accessibility data
// example: "VIDEO TITLE - 49 seconds - play video"
// "VIDEO TITLE - 1 minute, 1 second - play video"
final String accessibilityLabel = reelInfo.getObject("accessibility")
.getObject("accessibilityData").getString("label");
if (accessibilityLabel == null || timeAgoParser == null) {
return 0;
}
// This approach may be language dependent
final String[] labelParts = accessibilityLabel.split(" [\u2013-] ");
if (labelParts.length > 2) {
final String textualDuration = labelParts[labelParts.length - 2];
return timeAgoParser.parseDuration(textualDuration);
}
return -1;
}
@Override @Override
public long getViewCount() throws ParsingException { public long getViewCount() throws ParsingException {
final String viewCountText = getTextFromObject(reelInfo.getObject("viewCountText")); final String viewCountText = getTextFromObject(reelInfo.getObject("viewCountText"));
@ -117,6 +90,11 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
return false; return false;
} }
@Override
public long getDuration() throws ParsingException {
return -1;
}
@Override @Override
public String getUploaderName() throws ParsingException { public String getUploaderName() throws ParsingException {
return null; return null;

View File

@ -50,7 +50,7 @@ public interface StreamInfoItemExtractor extends InfoItemExtractor {
/** /**
* Get the stream duration in seconds * Get the stream duration in seconds
* *
* @return the stream duration in seconds * @return the stream duration in seconds or -1 if no duration is available
* @throws ParsingException if there is an error in the extraction * @throws ParsingException if there is an error in the extraction
*/ */
long getDuration() throws ParsingException; long getDuration() throws ParsingException;

View File

@ -41,10 +41,10 @@
"same-origin; report-to\u003d\"youtube_main\"" "same-origin; report-to\u003d\"youtube_main\""
], ],
"date": [ "date": [
"Fri, 08 Dec 2023 19:38:04 GMT" "Thu, 21 Dec 2023 19:53:52 GMT"
], ],
"expires": [ "expires": [
"Fri, 08 Dec 2023 19:38:04 GMT" "Thu, 21 Dec 2023 19:53:52 GMT"
], ],
"origin-trial": [ "origin-trial": [
"AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9" "AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,9 +62,9 @@
"ESF" "ESF"
], ],
"set-cookie": [ "set-cookie": [
"YSC\u003dXVJaGz18ttE; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone", "YSC\u003d52XN8PrKcOs; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dSat, 13-Mar-2021 19:38:04 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone", "VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 26-Mar-2021 19:53:52 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"CONSENT\u003dPENDING+916; expires\u003dSun, 07-Dec-2025 19:38:04 GMT; path\u003d/; domain\u003d.youtube.com; Secure" "CONSENT\u003dPENDING+032; expires\u003dSat, 20-Dec-2025 19:53:52 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
], ],
"strict-transport-security": [ "strict-transport-security": [
"max-age\u003d31536000" "max-age\u003d31536000"