From 81459e289f573284e846eebfa53ce98ce4ac5c69 Mon Sep 17 00:00:00 2001 From: wb9688 Date: Sat, 18 Jul 2020 09:50:22 +0200 Subject: [PATCH] Fix age restricted YouTube videos --- .../extractors/YoutubeStreamExtractor.java | 69 ++++++++++++++----- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index dca5e5fb..a1ac1296 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -21,8 +21,8 @@ import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoPatternsManager; import org.schabi.newpipe.extractor.services.youtube.ItagItem; -import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; +import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.Description; import org.schabi.newpipe.extractor.stream.Frameset; @@ -52,7 +52,10 @@ import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.*; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonResponse; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromNavigationEndpoint; import static org.schabi.newpipe.extractor.utils.JsonUtils.EMPTY_STRING; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; @@ -115,7 +118,11 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override public String getName() throws ParsingException { assertPageFetched(); - String title = getTextFromObject(getVideoPrimaryInfoRenderer().getObject("title")); + String title = null; + + try { + title = getTextFromObject(getVideoPrimaryInfoRenderer().getObject("title")); + } catch (ParsingException ignored) { } if (isNullOrEmpty(title)) { title = playerResponse.getObject("videoDetails").getString("title"); @@ -193,11 +200,13 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Nonnull @Override - public Description getDescription() throws ParsingException { + public Description getDescription() { assertPageFetched(); // description with more info on links - String description = getTextFromObject(getVideoSecondaryInfoRenderer().getObject("description"), true); - if (description != null && !description.isEmpty()) return new Description(description, Description.HTML); + try { + String description = getTextFromObject(getVideoSecondaryInfoRenderer().getObject("description"), true); + if (description != null && !description.isEmpty()) return new Description(description, Description.HTML); + } catch (ParsingException ignored) { } // raw non-html description return new Description(playerResponse.getObject("videoDetails").getString("shortDescription"), Description.PLAIN_TEXT); @@ -246,8 +255,12 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override public long getViewCount() throws ParsingException { assertPageFetched(); - String views = getTextFromObject(getVideoPrimaryInfoRenderer().getObject("viewCount") + String views = null; + + try { + views = getTextFromObject(getVideoPrimaryInfoRenderer().getObject("viewCount") .getObject("videoViewCountRenderer").getObject("viewCount")); + } catch (ParsingException ignored) {} if (isNullOrEmpty(views)) { views = playerResponse.getObject("videoDetails").getString("viewCount"); @@ -279,6 +292,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { } catch (NumberFormatException nfe) { throw new ParsingException("Could not parse \"" + likesString + "\" as an Integer", nfe); } catch (Exception e) { + if (ageLimit == 18) return -1; throw new ParsingException("Could not get like count", e); } } @@ -302,6 +316,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { } catch (NumberFormatException nfe) { throw new ParsingException("Could not parse \"" + dislikesString + "\" as an Integer", nfe); } catch (Exception e) { + if (ageLimit == 18) return -1; throw new ParsingException("Could not get dislike count", e); } } @@ -311,14 +326,18 @@ public class YoutubeStreamExtractor extends StreamExtractor { public String getUploaderUrl() throws ParsingException { assertPageFetched(); + try { String uploaderUrl = getUrlFromNavigationEndpoint(getVideoSecondaryInfoRenderer() .getObject("owner").getObject("videoOwnerRenderer").getObject("navigationEndpoint")); - if (uploaderUrl != null && !uploaderUrl.isEmpty()) return uploaderUrl; - + if (!isNullOrEmpty(uploaderUrl)) { + return uploaderUrl; + } + } catch (ParsingException ignored) { } String uploaderId = playerResponse.getObject("videoDetails").getString("channelId"); - if (uploaderId != null && !uploaderId.isEmpty()) + if (!isNullOrEmpty(uploaderId)) { return YoutubeChannelLinkHandlerFactory.getInstance().getUrl("channel/" + uploaderId); + } throw new ParsingException("Could not get uploader url"); } @@ -327,8 +346,13 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override public String getUploaderName() throws ParsingException { assertPageFetched(); - String uploaderName = getTextFromObject(getVideoSecondaryInfoRenderer().getObject("owner") + + String uploaderName = null; + + try { + uploaderName = getTextFromObject(getVideoSecondaryInfoRenderer().getObject("owner") .getObject("videoOwnerRenderer").getObject("title")); + } catch (ParsingException ignored) { } if (isNullOrEmpty(uploaderName)) { uploaderName = playerResponse.getObject("videoDetails").getString("author"); @@ -343,14 +367,20 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override public String getUploaderAvatarUrl() throws ParsingException { assertPageFetched(); - try { - String url = getVideoSecondaryInfoRenderer().getObject("owner").getObject("videoOwnerRenderer") - .getObject("thumbnail").getArray("thumbnails").getObject(0).getString("url"); - return fixThumbnailUrl(url); - } catch (Exception e) { - throw new ParsingException("Could not get uploader avatar url", e); + String url = null; + + try { + url = getVideoSecondaryInfoRenderer().getObject("owner").getObject("videoOwnerRenderer") + .getObject("thumbnail").getArray("thumbnails").getObject(0).getString("url"); + } catch (ParsingException ignored) { } + + if (isNullOrEmpty(url)) { + if (ageLimit == 18) return ""; + throw new ParsingException("Could not get uploader avatar URL"); } + + return fixThumbnailUrl(url); } @Nonnull @@ -872,7 +902,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { } } - if (videoPrimaryInfoRenderer == null) { + if (isNullOrEmpty(videoPrimaryInfoRenderer)) { throw new ParsingException("Could not find videoPrimaryInfoRenderer"); } @@ -894,7 +924,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { } } - if (videoSecondaryInfoRenderer == null) { + if (isNullOrEmpty(videoSecondaryInfoRenderer)) { throw new ParsingException("Could not find videoSecondaryInfoRenderer"); } @@ -904,6 +934,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Nonnull private static String getVideoInfoUrl(final String id, final String sts) { + // TODO: Try parsing embedded_player_response first return "https://www.youtube.com/get_video_info?" + "video_id=" + id + "&eurl=https://youtube.googleapis.com/v/" + id + "&sts=" + sts + "&ps=default&gl=US&hl=en";