Skip to content

Commit 4cc99f9

Browse files
committed
[YouTube] Apply changes in InfoItemExtractors except YouTube Music ones
1 parent adfad08 commit 4cc99f9

7 files changed

Lines changed: 164 additions & 106 deletions

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelInfoItemExtractor.java

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,41 @@
1-
package org.schabi.newpipe.extractor.services.youtube.extractors;
2-
3-
import com.grack.nanojson.JsonObject;
4-
5-
import org.schabi.newpipe.extractor.ListExtractor;
6-
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
7-
import org.schabi.newpipe.extractor.exceptions.ParsingException;
8-
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
9-
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
10-
import org.schabi.newpipe.extractor.utils.Utils;
11-
12-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl;
13-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
14-
151
/*
162
* Created by Christian Schabesberger on 12.02.17.
173
*
184
* Copyright (C) Christian Schabesberger 2017 <chris.schabesberger@mailbox.org>
19-
* YoutubeChannelInfoItemExtractor.java is part of NewPipe.
5+
* YoutubeChannelInfoItemExtractor.java is part of NewPipe Extractor.
206
*
21-
* NewPipe is free software: you can redistribute it and/or modify
7+
* NewPipe Extractor is free software: you can redistribute it and/or modify
228
* it under the terms of the GNU General Public License as published by
239
* the Free Software Foundation, either version 3 of the License, or
2410
* (at your option) any later version.
2511
*
26-
* NewPipe is distributed in the hope that it will be useful,
12+
* NewPipe Extractor is distributed in the hope that it will be useful,
2713
* but WITHOUT ANY WARRANTY; without even the implied warranty of
28-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2915
* GNU General Public License for more details.
3016
*
3117
* You should have received a copy of the GNU General Public License
32-
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
18+
* along with NewPipe Extractor. If not, see <https://www.gnu.org/licenses/>.
3319
*/
3420

21+
package org.schabi.newpipe.extractor.services.youtube.extractors;
22+
23+
import com.grack.nanojson.JsonObject;
24+
25+
import org.schabi.newpipe.extractor.Image;
26+
import org.schabi.newpipe.extractor.ListExtractor;
27+
import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor;
28+
import org.schabi.newpipe.extractor.exceptions.ParsingException;
29+
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
30+
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
31+
import org.schabi.newpipe.extractor.utils.Utils;
32+
33+
import javax.annotation.Nonnull;
34+
import java.util.List;
35+
36+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
37+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailsFromInfoItem;
38+
3539
public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor {
3640
private final JsonObject channelInfoItem;
3741
/**
@@ -53,15 +57,13 @@ public YoutubeChannelInfoItemExtractor(final JsonObject channelInfoItem) {
5357
this.withHandle = wHandle;
5458
}
5559

60+
@Nonnull
5661
@Override
57-
public String getThumbnailUrl() throws ParsingException {
62+
public List<Image> getThumbnails() throws ParsingException {
5863
try {
59-
final String url = channelInfoItem.getObject("thumbnail").getArray("thumbnails")
60-
.getObject(0).getString("url");
61-
62-
return fixThumbnailUrl(url);
64+
return getThumbnailsFromInfoItem(channelInfoItem);
6365
} catch (final Exception e) {
64-
throw new ParsingException("Could not get thumbnail url", e);
66+
throw new ParsingException("Could not get thumbnails", e);
6567
}
6668
}
6769

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeCommentsInfoItemExtractor.java

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package org.schabi.newpipe.extractor.services.youtube.extractors;
22

3-
import com.grack.nanojson.JsonArray;
43
import com.grack.nanojson.JsonObject;
4+
5+
import org.schabi.newpipe.extractor.Image;
56
import org.schabi.newpipe.extractor.Page;
67
import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor;
78
import org.schabi.newpipe.extractor.exceptions.ParsingException;
@@ -11,9 +12,12 @@
1112
import org.schabi.newpipe.extractor.utils.JsonUtils;
1213
import org.schabi.newpipe.extractor.utils.Utils;
1314

15+
import javax.annotation.Nonnull;
1416
import javax.annotation.Nullable;
17+
import java.util.List;
1518

1619
import static org.schabi.newpipe.extractor.comments.CommentsInfoItem.UNKNOWN_REPLY_COUNT;
20+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
1721
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
1822

1923
public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor {
@@ -42,20 +46,25 @@ private JsonObject getCommentRenderer() throws ParsingException {
4246
return commentRenderer;
4347
}
4448

49+
@Nonnull
50+
private List<Image> getAuthorThumbnails() throws ParsingException {
51+
try {
52+
return getImagesFromThumbnailsArray(JsonUtils.getArray(getCommentRenderer(),
53+
"authorThumbnail.thumbnails"));
54+
} catch (final Exception e) {
55+
throw new ParsingException("Could not get author thumbnails", e);
56+
}
57+
}
58+
4559
@Override
4660
public String getUrl() throws ParsingException {
4761
return url;
4862
}
4963

64+
@Nonnull
5065
@Override
51-
public String getThumbnailUrl() throws ParsingException {
52-
try {
53-
final JsonArray arr = JsonUtils.getArray(getCommentRenderer(),
54-
"authorThumbnail.thumbnails");
55-
return JsonUtils.getString(arr.getObject(2), "url");
56-
} catch (final Exception e) {
57-
throw new ParsingException("Could not get thumbnail url", e);
58-
}
66+
public List<Image> getThumbnails() throws ParsingException {
67+
return getAuthorThumbnails();
5968
}
6069

6170
@Override
@@ -204,15 +213,10 @@ public String getCommentId() throws ParsingException {
204213
}
205214
}
206215

216+
@Nonnull
207217
@Override
208-
public String getUploaderAvatarUrl() throws ParsingException {
209-
try {
210-
final JsonArray arr = JsonUtils.getArray(getCommentRenderer(),
211-
"authorThumbnail.thumbnails");
212-
return JsonUtils.getString(arr.getObject(2), "url");
213-
} catch (final Exception e) {
214-
throw new ParsingException("Could not get author thumbnail", e);
215-
}
218+
public List<Image> getUploaderAvatars() throws ParsingException {
219+
return getAuthorThumbnails();
216220
}
217221

218222
@Override
@@ -228,6 +232,7 @@ public boolean isPinned() throws ParsingException {
228232
return getCommentRenderer().has("pinnedCommentBadge");
229233
}
230234

235+
@Override
231236
public boolean isUploaderVerified() throws ParsingException {
232237
return getCommentRenderer().has("authorCommentBadge");
233238
}
@@ -261,7 +266,7 @@ public int getReplyCount() throws ParsingException {
261266
}
262267

263268
@Override
264-
public Page getReplies() throws ParsingException {
269+
public Page getReplies() {
265270
try {
266271
final String id = JsonUtils.getString(
267272
JsonUtils.getArray(json, "replies.commentRepliesRenderer.contents")

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeFeedInfoItemExtractor.java

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package org.schabi.newpipe.extractor.services.youtube.extractors;
22

33
import org.jsoup.nodes.Element;
4+
import org.schabi.newpipe.extractor.Image;
5+
import org.schabi.newpipe.extractor.Image.ResolutionLevel;
46
import org.schabi.newpipe.extractor.exceptions.ParsingException;
57
import org.schabi.newpipe.extractor.localization.DateWrapper;
68
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
79
import org.schabi.newpipe.extractor.stream.StreamType;
810

11+
import javax.annotation.Nonnull;
912
import javax.annotation.Nullable;
1013
import java.time.OffsetDateTime;
1114
import java.time.format.DateTimeParseException;
15+
import java.util.List;
1216

1317
public class YoutubeFeedInfoItemExtractor implements StreamInfoItemExtractor {
1418
private final Element entryElement;
@@ -51,12 +55,6 @@ public String getUploaderUrl() {
5155
return entryElement.select("author > uri").first().text();
5256
}
5357

54-
@Nullable
55-
@Override
56-
public String getUploaderAvatarUrl() throws ParsingException {
57-
return null;
58-
}
59-
6058
@Override
6159
public boolean isUploaderVerified() throws ParsingException {
6260
return false;
@@ -89,12 +87,51 @@ public String getUrl() {
8987
return entryElement.getElementsByTag("link").first().attr("href");
9088
}
9189

90+
@Nonnull
9291
@Override
93-
public String getThumbnailUrl() {
92+
public List<Image> getThumbnails() {
93+
final Element thumbnailElement = entryElement.getElementsByTag("media:thumbnail").first();
94+
if (thumbnailElement == null) {
95+
return List.of();
96+
}
97+
98+
final String feedThumbnailUrl = thumbnailElement.attr("url");
99+
100+
// If the thumbnail URL is empty, it means that no thumbnail is available, return an empty
101+
// list in this case
102+
if (feedThumbnailUrl.isEmpty()) {
103+
return List.of();
104+
}
105+
94106
// The hqdefault thumbnail has some black bars at the top and at the bottom, while the
95107
// mqdefault doesn't, so return the mqdefault one. It should always exist, according to
96108
// https://stackoverflow.com/a/20542029/9481500.
97-
return entryElement.getElementsByTag("media:thumbnail").first().attr("url")
98-
.replace("hqdefault", "mqdefault");
109+
final String newFeedThumbnailUrl = feedThumbnailUrl.replace("hqdefault", "mqdefault");
110+
111+
int height;
112+
int width;
113+
114+
// If the new thumbnail URL is equal to the feed one, it means that a different image
115+
// resolution is used on feeds, so use the height and width provided instead of the
116+
// mqdefault ones
117+
if (newFeedThumbnailUrl.equals(feedThumbnailUrl)) {
118+
try {
119+
height = Integer.parseInt(thumbnailElement.attr("height"));
120+
} catch (final NumberFormatException e) {
121+
height = Image.HEIGHT_UNKNOWN;
122+
}
123+
124+
try {
125+
width = Integer.parseInt(thumbnailElement.attr("width"));
126+
} catch (final NumberFormatException e) {
127+
width = Image.WIDTH_UNKNOWN;
128+
}
129+
} else {
130+
height = 320;
131+
width = 180;
132+
}
133+
134+
return List.of(
135+
new Image(newFeedThumbnailUrl, height, width, ResolutionLevel.fromHeight(height)));
99136
}
100137
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixOrPlaylistInfoItemExtractor.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.extractPlaylistTypeFromPlaylistUrl;
44
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
5-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailUrlFromInfoItem;
5+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailsFromInfoItem;
66
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
77

88
import com.grack.nanojson.JsonObject;
99

10+
import org.schabi.newpipe.extractor.Image;
1011
import org.schabi.newpipe.extractor.ListExtractor;
1112
import org.schabi.newpipe.extractor.exceptions.ParsingException;
1213
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
1314
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
1415
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
1516

1617
import javax.annotation.Nonnull;
18+
import java.util.List;
1719

1820
public class YoutubeMixOrPlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
1921
private final JsonObject mixInfoItem;
@@ -40,9 +42,10 @@ public String getUrl() throws ParsingException {
4042
return url;
4143
}
4244

45+
@Nonnull
4346
@Override
44-
public String getThumbnailUrl() throws ParsingException {
45-
return getThumbnailUrlFromInfoItem(mixInfoItem);
47+
public List<Image> getThumbnails() throws ParsingException {
48+
return getThumbnailsFromInfoItem(mixInfoItem);
4649
}
4750

4851
@Override
@@ -75,7 +78,7 @@ public long getStreamCount() throws ParsingException {
7578
return Integer.parseInt(countString);
7679
} catch (final NumberFormatException ignored) {
7780
// un-parsable integer: this is a mix with infinite items and "50+" as count string
78-
// (though youtube music mixes do not necessarily have an infinite count of songs)
81+
// (though YouTube Music mixes do not necessarily have an infinite count of songs)
7982
return ListExtractor.ITEM_COUNT_INFINITE;
8083
}
8184
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistInfoItemExtractor.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,31 @@
22

33
import com.grack.nanojson.JsonArray;
44
import com.grack.nanojson.JsonObject;
5+
6+
import org.schabi.newpipe.extractor.Image;
57
import org.schabi.newpipe.extractor.exceptions.ParsingException;
68
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
79
import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper;
810
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory;
911
import org.schabi.newpipe.extractor.utils.Utils;
1012

11-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl;
13+
import javax.annotation.Nonnull;
14+
import java.util.List;
15+
16+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
1217
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
1318
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromObject;
1419

15-
1620
public class YoutubePlaylistInfoItemExtractor implements PlaylistInfoItemExtractor {
1721
private final JsonObject playlistInfoItem;
1822

1923
public YoutubePlaylistInfoItemExtractor(final JsonObject playlistInfoItem) {
2024
this.playlistInfoItem = playlistInfoItem;
2125
}
2226

27+
@Nonnull
2328
@Override
24-
public String getThumbnailUrl() throws ParsingException {
29+
public List<Image> getThumbnails() throws ParsingException {
2530
try {
2631
JsonArray thumbnails = playlistInfoItem.getArray("thumbnails")
2732
.getObject(0)
@@ -31,9 +36,9 @@ public String getThumbnailUrl() throws ParsingException {
3136
.getArray("thumbnails");
3237
}
3338

34-
return fixThumbnailUrl(thumbnails.getObject(0).getString("url"));
39+
return getImagesFromThumbnailsArray(thumbnails);
3540
} catch (final Exception e) {
36-
throw new ParsingException("Could not get thumbnail url", e);
41+
throw new ParsingException("Could not get thumbnails", e);
3742
}
3843
}
3944

0 commit comments

Comments
 (0)