[YouTube] Apply changes in InfoItemExtractors except YouTube Music ones

This commit is contained in:
AudricV 2022-07-22 21:34:12 +02:00
parent adfad086ac
commit 4cc99f9ce1
No known key found for this signature in database
GPG Key ID: DA92EC7905614198
7 changed files with 166 additions and 108 deletions

View File

@ -1,7 +1,28 @@
/*
* Created by Christian Schabesberger on 12.02.17.
*
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
* YoutubeChannelInfoItemExtractor.java is part of NewPipe Extractor.
*
* NewPipe Extractor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe Extractor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe Extractor. If not, see <https://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
@ -9,28 +30,11 @@ import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
import javax.annotation.Nonnull;
import java.util.List;
/*
* Created by Christian Schabesberger on 12.02.17.
*
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
* YoutubeChannelInfoItemExtractor.java is part of NewPipe.
*
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailsFromInfoItem;
public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor {
private final JsonObject channelInfoItem;
@ -53,15 +57,13 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor
this.withHandle = wHandle;
}
@Nonnull
@Override
public String getThumbnailUrl() throws ParsingException {
public List<Image> getThumbnails() throws ParsingException {
try {
final String url = channelInfoItem.getObject("thumbnail").getArray("thumbnails")
.getObject(0).getString("url");
return fixThumbnailUrl(url);
return getThumbnailsFromInfoItem(channelInfoItem);
} catch (final Exception e) {
throw new ParsingException("Could not get thumbnail url", e);
throw new ParsingException("Could not get thumbnails", e);
}
}

View File

@ -1,7 +1,8 @@
package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
@ -11,9 +12,12 @@ import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.utils.JsonUtils;
import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import static org.schabi.newpipe.extractor.comments.CommentsInfoItem.UNKNOWN_REPLY_COUNT;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor {
@ -42,20 +46,25 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
return commentRenderer;
}
@Nonnull
private List<Image> getAuthorThumbnails() throws ParsingException {
try {
return getImagesFromThumbnailsArray(JsonUtils.getArray(getCommentRenderer(),
"authorThumbnail.thumbnails"));
} catch (final Exception e) {
throw new ParsingException("Could not get author thumbnails", e);
}
}
@Override
public String getUrl() throws ParsingException {
return url;
}
@Nonnull
@Override
public String getThumbnailUrl() throws ParsingException {
try {
final JsonArray arr = JsonUtils.getArray(getCommentRenderer(),
"authorThumbnail.thumbnails");
return JsonUtils.getString(arr.getObject(2), "url");
} catch (final Exception e) {
throw new ParsingException("Could not get thumbnail url", e);
}
public List<Image> getThumbnails() throws ParsingException {
return getAuthorThumbnails();
}
@Override
@ -204,15 +213,10 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
}
}
@Nonnull
@Override
public String getUploaderAvatarUrl() throws ParsingException {
try {
final JsonArray arr = JsonUtils.getArray(getCommentRenderer(),
"authorThumbnail.thumbnails");
return JsonUtils.getString(arr.getObject(2), "url");
} catch (final Exception e) {
throw new ParsingException("Could not get author thumbnail", e);
}
public List<Image> getUploaderAvatars() throws ParsingException {
return getAuthorThumbnails();
}
@Override
@ -228,6 +232,7 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
return getCommentRenderer().has("pinnedCommentBadge");
}
@Override
public boolean isUploaderVerified() throws ParsingException {
return getCommentRenderer().has("authorCommentBadge");
}
@ -261,7 +266,7 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
}
@Override
public Page getReplies() throws ParsingException {
public Page getReplies() {
try {
final String id = JsonUtils.getString(
JsonUtils.getArray(json, "replies.commentRepliesRenderer.contents")

View File

@ -1,14 +1,18 @@
package org.schabi.newpipe.extractor.services.youtube.extractors;
import org.jsoup.nodes.Element;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.Image.ResolutionLevel;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.time.OffsetDateTime;
import java.time.format.DateTimeParseException;
import java.util.List;
public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
private final Element entryElement;
@ -51,12 +55,6 @@ public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
return entryElement.select("author > uri").first().text();
}
@Nullable
@Override
public String getUploaderAvatarUrl() throws ParsingException {
return null;
}
@Override
public boolean isUploaderVerified() throws ParsingException {
return false;
@ -89,12 +87,51 @@ public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
return entryElement.getElementsByTag("link").first().attr("href");
}
@Nonnull
@Override
public String getThumbnailUrl() {
public List<Image> getThumbnails() {
final Element thumbnailElement = entryElement.getElementsByTag("media:thumbnail").first();
if (thumbnailElement == null) {
return List.of();
}
final String feedThumbnailUrl = thumbnailElement.attr("url");
// If the thumbnail URL is empty, it means that no thumbnail is available, return an empty
// list in this case
if (feedThumbnailUrl.isEmpty()) {
return List.of();
}
// The hqdefault thumbnail has some black bars at the top and at the bottom, while the
// mqdefault doesn't, so return the mqdefault one. It should always exist, according to
// https://stackoverflow.com/a/20542029/9481500.
return entryElement.getElementsByTag("media:thumbnail").first().attr("url")
.replace("hqdefault", "mqdefault");
final String newFeedThumbnailUrl = feedThumbnailUrl.replace("hqdefault", "mqdefault");
int height;
int width;
// If the new thumbnail URL is equal to the feed one, it means that a different image
// resolution is used on feeds, so use the height and width provided instead of the
// mqdefault ones
if (newFeedThumbnailUrl.equals(feedThumbnailUrl)) {
try {
height = Integer.parseInt(thumbnailElement.attr("height"));
} catch (final NumberFormatException e) {
height = Image.HEIGHT_UNKNOWN;
}
try {
width = Integer.parseInt(thumbnailElement.attr("width"));
} catch (final NumberFormatException e) {
width = Image.WIDTH_UNKNOWN;
}
} else {
height = 320;
width = 180;
}
return List.of(
new Image(newFeedThumbnailUrl, height, width, ResolutionLevel.fromHeight(height)));
}
}

View File

@ -2,11 +2,12 @@ package org.schabi.newpipe.extractor.services.youtube.extractors;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.extractPlaylistTypeFromPlaylistUrl;
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.getThumbnailsFromInfoItem;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
@ -14,6 +15,7 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
import javax.annotation.Nonnull;
import java.util.List;
public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
private final JsonObject mixInfoItem;
@ -40,9 +42,10 @@ public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemEx
return url;
}
@Nonnull
@Override
public String getThumbnailUrl() throws ParsingException {
return getThumbnailUrlFromInfoItem(mixInfoItem);
public List<Image> getThumbnails() throws ParsingException {
return getThumbnailsFromInfoItem(mixInfoItem);
}
@Override
@ -75,7 +78,7 @@ public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemEx
return Integer.parseInt(countString);
} catch (final NumberFormatException ignored) {
// un-parsable integer: this is a mix with infinite items and "50+" as count string
// (though youtube music mixes do not necessarily have an infinite count of songs)
// (though YouTube Music mixes do not necessarily have an infinite count of songs)
return ListExtractor.ITEM_COUNT_INFINITE;
}
}

View File

@ -2,17 +2,21 @@ package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl;
import javax.annotation.Nonnull;
import java.util.List;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromObject;
public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
private final JsonObject playlistInfoItem;
@ -20,8 +24,9 @@ public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtract
this.playlistInfoItem = playlistInfoItem;
}
@Nonnull
@Override
public String getThumbnailUrl() throws ParsingException {
public List<Image> getThumbnails() throws ParsingException {
try {
JsonArray thumbnails = playlistInfoItem.getArray("thumbnails")
.getObject(0)
@ -31,9 +36,9 @@ public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtract
.getArray("thumbnails");
}
return fixThumbnailUrl(thumbnails.getObject(0).getString("url"));
return getImagesFromThumbnailsArray(thumbnails);
} catch (final Exception e) {
throw new ParsingException("Could not get thumbnail url", e);
throw new ParsingException("Could not get thumbnails", e);
}
}

View File

@ -1,6 +1,8 @@
package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.localization.TimeAgoParser;
@ -13,9 +15,11 @@ import javax.annotation.Nonnull;
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.getThumbnailsFromInfoItem;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import java.util.List;
/**
* A {@link StreamInfoItemExtractor} for YouTube's {@code reelItemRenderers}.
*
@ -53,9 +57,10 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
}
}
@Nonnull
@Override
public String getThumbnailUrl() throws ParsingException {
return getThumbnailUrlFromInfoItem(reelInfo);
public List<Image> getThumbnails() throws ParsingException {
return getThumbnailsFromInfoItem(reelInfo);
}
@Override
@ -101,7 +106,7 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
}
@Override
public boolean isShortFormContent() throws ParsingException {
public boolean isShortFormContent() {
return true;
}
@ -122,12 +127,6 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
return null;
}
@Nullable
@Override
public String getUploaderAvatarUrl() throws ParsingException {
return null;
}
@Override
public boolean isUploaderVerified() throws ParsingException {
return false;

View File

@ -1,7 +1,33 @@
/*
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
* YoutubeStreamInfoItemExtractor.java is part of NewPipe Extractor.
*
* NewPipe Extractor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe Extractor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe Extractor. If not, see <https://www.gnu.org/licenses/>.
*/
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.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
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.Image;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.localization.TimeAgoParser;
@ -15,35 +41,14 @@ import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.Pattern;
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 <chris.schabesberger@mailbox.org>
* YoutubeStreamInfoItemExtractor.java is part of NewPipe.
*
* NewPipe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NewPipe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
private static final Pattern ACCESSIBILITY_DATA_VIEW_COUNT_REGEX =
@ -215,21 +220,22 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
return url;
}
@Nullable
@Nonnull
@Override
public String getUploaderAvatarUrl() throws ParsingException {
public List<Image> getUploaderAvatars() throws ParsingException {
if (videoInfo.has("channelThumbnailSupportedRenderers")) {
return JsonUtils.getArray(videoInfo, "channelThumbnailSupportedRenderers"
+ ".channelThumbnailWithLinkRenderer.thumbnail.thumbnails")
.getObject(0).getString("url");
return getImagesFromThumbnailsArray(JsonUtils.getArray(videoInfo,
// CHECKSTYLE:OFF
"channelThumbnailSupportedRenderers.channelThumbnailWithLinkRenderer.thumbnail.thumbnails"));
// CHECKSTYLE:ON
}
if (videoInfo.has("channelThumbnail")) {
return JsonUtils.getArray(videoInfo, "channelThumbnail.thumbnails")
.getObject(0).getString("url");
return getImagesFromThumbnailsArray(
JsonUtils.getArray(videoInfo, "channelThumbnail.thumbnails"));
}
return null;
return List.of();
}
@Override
@ -371,9 +377,10 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
videoInfoTitleAccessibilityData)));
}
@Nonnull
@Override
public String getThumbnailUrl() throws ParsingException {
return getThumbnailUrlFromInfoItem(videoInfo);
public List<Image> getThumbnails() throws ParsingException {
return getThumbnailsFromInfoItem(videoInfo);
}
private boolean isPremium() {
@ -409,10 +416,10 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
@Nullable
@Override
public String getShortDescription() throws ParsingException {
if (videoInfo.has("detailedMetadataSnippets")) {
return getTextFromObject(videoInfo.getArray("detailedMetadataSnippets")
.getObject(0).getObject("snippetText"));
.getObject(0)
.getObject("snippetText"));
}
if (videoInfo.has("descriptionSnippet")) {