[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; package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; 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.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl; import javax.annotation.Nonnull;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; import java.util.List;
/* import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
* Created by Christian Schabesberger on 12.02.17. import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailsFromInfoItem;
*
* 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/>.
*/
public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor { public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor {
private final JsonObject channelInfoItem; private final JsonObject channelInfoItem;
@ -53,15 +57,13 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor
this.withHandle = wHandle; this.withHandle = wHandle;
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public List<Image> getThumbnails() throws ParsingException {
try { try {
final String url = channelInfoItem.getObject("thumbnail").getArray("thumbnails") return getThumbnailsFromInfoItem(channelInfoItem);
.getObject(0).getString("url");
return fixThumbnailUrl(url);
} catch (final Exception e) { } 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; package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor; import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; 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.JsonUtils;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; 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.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; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor { public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor {
@ -42,20 +46,25 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
return commentRenderer; 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 @Override
public String getUrl() throws ParsingException { public String getUrl() throws ParsingException {
return url; return url;
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public List<Image> getThumbnails() throws ParsingException {
try { return getAuthorThumbnails();
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);
}
} }
@Override @Override
@ -204,15 +213,10 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
} }
} }
@Nonnull
@Override @Override
public String getUploaderAvatarUrl() throws ParsingException { public List<Image> getUploaderAvatars() throws ParsingException {
try { return getAuthorThumbnails();
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);
}
} }
@Override @Override
@ -228,6 +232,7 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
return getCommentRenderer().has("pinnedCommentBadge"); return getCommentRenderer().has("pinnedCommentBadge");
} }
@Override
public boolean isUploaderVerified() throws ParsingException { public boolean isUploaderVerified() throws ParsingException {
return getCommentRenderer().has("authorCommentBadge"); return getCommentRenderer().has("authorCommentBadge");
} }
@ -261,7 +266,7 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
} }
@Override @Override
public Page getReplies() throws ParsingException { public Page getReplies() {
try { try {
final String id = JsonUtils.getString( final String id = JsonUtils.getString(
JsonUtils.getArray(json, "replies.commentRepliesRenderer.contents") JsonUtils.getArray(json, "replies.commentRepliesRenderer.contents")

View File

@ -1,14 +1,18 @@
package org.schabi.newpipe.extractor.services.youtube.extractors; package org.schabi.newpipe.extractor.services.youtube.extractors;
import org.jsoup.nodes.Element; 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.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.localization.DateWrapper;
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 javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.List;
public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor { public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
private final Element entryElement; private final Element entryElement;
@ -51,12 +55,6 @@ public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
return entryElement.select("author > uri").first().text(); return entryElement.select("author > uri").first().text();
} }
@Nullable
@Override
public String getUploaderAvatarUrl() throws ParsingException {
return null;
}
@Override @Override
public boolean isUploaderVerified() throws ParsingException { public boolean isUploaderVerified() throws ParsingException {
return false; return false;
@ -89,12 +87,51 @@ public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
return entryElement.getElementsByTag("link").first().attr("href"); return entryElement.getElementsByTag("link").first().attr("href");
} }
@Nonnull
@Override @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 // 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 // mqdefault doesn't, so return the mqdefault one. It should always exist, according to
// https://stackoverflow.com/a/20542029/9481500. // https://stackoverflow.com/a/20542029/9481500.
return entryElement.getElementsByTag("media:thumbnail").first().attr("url") final String newFeedThumbnailUrl = feedThumbnailUrl.replace("hqdefault", "mqdefault");
.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.extractPlaylistTypeFromPlaylistUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; 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 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.ListExtractor; import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo; 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 org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.List;
public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor { public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
private final JsonObject mixInfoItem; private final JsonObject mixInfoItem;
@ -40,9 +42,10 @@ public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemEx
return url; return url;
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public List<Image> getThumbnails() throws ParsingException {
return getThumbnailUrlFromInfoItem(mixInfoItem); return getThumbnailsFromInfoItem(mixInfoItem);
} }
@Override @Override
@ -75,7 +78,7 @@ public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemEx
return Integer.parseInt(countString); return Integer.parseInt(countString);
} catch (final NumberFormatException ignored) { } catch (final NumberFormatException ignored) {
// un-parsable integer: this is a mix with infinite items and "50+" as count string // 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; 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.JsonArray;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
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.playlist.PlaylistInfoItemExtractor; import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils; 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.getTextFromObject;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromObject; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromObject;
public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtractor { public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
private final JsonObject playlistInfoItem; private final JsonObject playlistInfoItem;
@ -20,8 +24,9 @@ public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtract
this.playlistInfoItem = playlistInfoItem; this.playlistInfoItem = playlistInfoItem;
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public List<Image> getThumbnails() throws ParsingException {
try { try {
JsonArray thumbnails = playlistInfoItem.getArray("thumbnails") JsonArray thumbnails = playlistInfoItem.getArray("thumbnails")
.getObject(0) .getObject(0)
@ -31,9 +36,9 @@ public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtract
.getArray("thumbnails"); .getArray("thumbnails");
} }
return fixThumbnailUrl(thumbnails.getObject(0).getString("url")); return getImagesFromThumbnailsArray(thumbnails);
} catch (final Exception e) { } 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; package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
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.localization.TimeAgoParser;
@ -13,9 +15,11 @@ 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.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 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}.
* *
@ -53,9 +57,10 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
} }
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public List<Image> getThumbnails() throws ParsingException {
return getThumbnailUrlFromInfoItem(reelInfo); return getThumbnailsFromInfoItem(reelInfo);
} }
@Override @Override
@ -101,7 +106,7 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
} }
@Override @Override
public boolean isShortFormContent() throws ParsingException { public boolean isShortFormContent() {
return true; return true;
} }
@ -122,12 +127,6 @@ public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {
return null; return null;
} }
@Nullable
@Override
public String getUploaderAvatarUrl() throws ParsingException {
return null;
}
@Override @Override
public boolean isUploaderVerified() throws ParsingException { public boolean isUploaderVerified() throws ParsingException {
return false; 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; 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.JsonArray;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
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.localization.TimeAgoParser;
@ -15,35 +41,14 @@ import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.time.Instant; import java.time.Instant;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.Pattern; 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 { public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
private static final Pattern ACCESSIBILITY_DATA_VIEW_COUNT_REGEX = private static final Pattern ACCESSIBILITY_DATA_VIEW_COUNT_REGEX =
@ -215,21 +220,22 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
return url; return url;
} }
@Nullable @Nonnull
@Override @Override
public String getUploaderAvatarUrl() throws ParsingException { public List<Image> getUploaderAvatars() throws ParsingException {
if (videoInfo.has("channelThumbnailSupportedRenderers")) { if (videoInfo.has("channelThumbnailSupportedRenderers")) {
return JsonUtils.getArray(videoInfo, "channelThumbnailSupportedRenderers" return getImagesFromThumbnailsArray(JsonUtils.getArray(videoInfo,
+ ".channelThumbnailWithLinkRenderer.thumbnail.thumbnails") // CHECKSTYLE:OFF
.getObject(0).getString("url"); "channelThumbnailSupportedRenderers.channelThumbnailWithLinkRenderer.thumbnail.thumbnails"));
// CHECKSTYLE:ON
} }
if (videoInfo.has("channelThumbnail")) { if (videoInfo.has("channelThumbnail")) {
return JsonUtils.getArray(videoInfo, "channelThumbnail.thumbnails") return getImagesFromThumbnailsArray(
.getObject(0).getString("url"); JsonUtils.getArray(videoInfo, "channelThumbnail.thumbnails"));
} }
return null; return List.of();
} }
@Override @Override
@ -371,9 +377,10 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
videoInfoTitleAccessibilityData))); videoInfoTitleAccessibilityData)));
} }
@Nonnull
@Override @Override
public String getThumbnailUrl() throws ParsingException { public List<Image> getThumbnails() throws ParsingException {
return getThumbnailUrlFromInfoItem(videoInfo); return getThumbnailsFromInfoItem(videoInfo);
} }
private boolean isPremium() { private boolean isPremium() {
@ -409,10 +416,10 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
@Nullable @Nullable
@Override @Override
public String getShortDescription() throws ParsingException { public String getShortDescription() throws ParsingException {
if (videoInfo.has("detailedMetadataSnippets")) { if (videoInfo.has("detailedMetadataSnippets")) {
return getTextFromObject(videoInfo.getArray("detailedMetadataSnippets") return getTextFromObject(videoInfo.getArray("detailedMetadataSnippets")
.getObject(0).getObject("snippetText")); .getObject(0)
.getObject("snippetText"));
} }
if (videoInfo.has("descriptionSnippet")) { if (videoInfo.has("descriptionSnippet")) {