@@ -118,7 +118,13 @@ public YoutubeStreamExtractor(StreamingService service, LinkHandler linkHandler)
118118 @ Override
119119 public String getName () throws ParsingException {
120120 assertPageFetched ();
121- String title = getTextFromObject (getVideoPrimaryInfoRenderer ().getObject ("title" ));
121+ String title = null ;
122+
123+ try {
124+ title = getTextFromObject (getVideoPrimaryInfoRenderer ().getObject ("title" ));
125+ } catch (ParsingException ignored ) {
126+ // age-restricted videos cause a ParsingException here
127+ }
122128
123129 if (isNullOrEmpty (title )) {
124130 title = playerResponse .getObject ("videoDetails" ).getString ("title" );
@@ -196,11 +202,15 @@ public String getThumbnailUrl() throws ParsingException {
196202
197203 @ Nonnull
198204 @ Override
199- public Description getDescription () throws ParsingException {
205+ public Description getDescription () {
200206 assertPageFetched ();
201207 // description with more info on links
202- String description = getTextFromObject (getVideoSecondaryInfoRenderer ().getObject ("description" ), true );
203- if (description != null && !description .isEmpty ()) return new Description (description , Description .HTML );
208+ try {
209+ String description = getTextFromObject (getVideoSecondaryInfoRenderer ().getObject ("description" ), true );
210+ if (description != null && !description .isEmpty ()) return new Description (description , Description .HTML );
211+ } catch (ParsingException ignored ) {
212+ // age-restricted videos cause a ParsingException here
213+ }
204214
205215 // raw non-html description
206216 return new Description (playerResponse .getObject ("videoDetails" ).getString ("shortDescription" ), Description .PLAIN_TEXT );
@@ -249,8 +259,14 @@ public long getTimeStamp() throws ParsingException {
249259 @ Override
250260 public long getViewCount () throws ParsingException {
251261 assertPageFetched ();
252- String views = getTextFromObject (getVideoPrimaryInfoRenderer ().getObject ("viewCount" )
262+ String views = null ;
263+
264+ try {
265+ views = getTextFromObject (getVideoPrimaryInfoRenderer ().getObject ("viewCount" )
253266 .getObject ("videoViewCountRenderer" ).getObject ("viewCount" ));
267+ } catch (ParsingException ignored ) {
268+ // age-restricted videos cause a ParsingException here
269+ }
254270
255271 if (isNullOrEmpty (views )) {
256272 views = playerResponse .getObject ("videoDetails" ).getString ("viewCount" );
@@ -282,6 +298,7 @@ public long getLikeCount() throws ParsingException {
282298 } catch (NumberFormatException nfe ) {
283299 throw new ParsingException ("Could not parse \" " + likesString + "\" as an Integer" , nfe );
284300 } catch (Exception e ) {
301+ if (ageLimit == 18 ) return -1 ;
285302 throw new ParsingException ("Could not get like count" , e );
286303 }
287304 }
@@ -305,6 +322,7 @@ public long getDislikeCount() throws ParsingException {
305322 } catch (NumberFormatException nfe ) {
306323 throw new ParsingException ("Could not parse \" " + dislikesString + "\" as an Integer" , nfe );
307324 } catch (Exception e ) {
325+ if (ageLimit == 18 ) return -1 ;
308326 throw new ParsingException ("Could not get dislike count" , e );
309327 }
310328 }
@@ -314,14 +332,20 @@ public long getDislikeCount() throws ParsingException {
314332 public String getUploaderUrl () throws ParsingException {
315333 assertPageFetched ();
316334
335+ try {
317336 String uploaderUrl = getUrlFromNavigationEndpoint (getVideoSecondaryInfoRenderer ()
318337 .getObject ("owner" ).getObject ("videoOwnerRenderer" ).getObject ("navigationEndpoint" ));
319- if (uploaderUrl != null && !uploaderUrl .isEmpty ()) return uploaderUrl ;
320-
338+ if (!isNullOrEmpty (uploaderUrl )) {
339+ return uploaderUrl ;
340+ }
341+ } catch (ParsingException ignored ) {
342+ // age-restricted videos cause a ParsingException here
343+ }
321344
322345 String uploaderId = playerResponse .getObject ("videoDetails" ).getString ("channelId" );
323- if (uploaderId != null && ! uploaderId . isEmpty ())
346+ if (! isNullOrEmpty ( uploaderId )) {
324347 return YoutubeChannelLinkHandlerFactory .getInstance ().getUrl ("channel/" + uploaderId );
348+ }
325349
326350 throw new ParsingException ("Could not get uploader url" );
327351 }
@@ -330,8 +354,13 @@ public String getUploaderUrl() throws ParsingException {
330354 @ Override
331355 public String getUploaderName () throws ParsingException {
332356 assertPageFetched ();
333- String uploaderName = getTextFromObject (getVideoSecondaryInfoRenderer ().getObject ("owner" )
357+
358+ String uploaderName = null ;
359+
360+ try {
361+ uploaderName = getTextFromObject (getVideoSecondaryInfoRenderer ().getObject ("owner" )
334362 .getObject ("videoOwnerRenderer" ).getObject ("title" ));
363+ } catch (ParsingException ignored ) { }
335364
336365 if (isNullOrEmpty (uploaderName )) {
337366 uploaderName = playerResponse .getObject ("videoDetails" ).getString ("author" );
@@ -346,14 +375,22 @@ public String getUploaderName() throws ParsingException {
346375 @ Override
347376 public String getUploaderAvatarUrl () throws ParsingException {
348377 assertPageFetched ();
378+
379+ String url = null ;
380+
349381 try {
350- String url = getVideoSecondaryInfoRenderer ().getObject ("owner" ).getObject ("videoOwnerRenderer" )
382+ url = getVideoSecondaryInfoRenderer ().getObject ("owner" ).getObject ("videoOwnerRenderer" )
351383 .getObject ("thumbnail" ).getArray ("thumbnails" ).getObject (0 ).getString ("url" );
384+ } catch (ParsingException ignored ) {
385+ // age-restricted videos cause a ParsingException here
386+ }
352387
353- return fixThumbnailUrl ( url );
354- } catch ( Exception e ) {
355- throw new ParsingException ("Could not get uploader avatar url" , e );
388+ if ( isNullOrEmpty ( url )) {
389+ if ( ageLimit == 18 ) return "" ;
390+ throw new ParsingException ("Could not get uploader avatar URL" );
356391 }
392+
393+ return fixThumbnailUrl (url );
357394 }
358395
359396 @ Nonnull
@@ -872,7 +909,7 @@ private JsonObject getVideoPrimaryInfoRenderer() throws ParsingException {
872909 }
873910 }
874911
875- if (videoPrimaryInfoRenderer == null ) {
912+ if (isNullOrEmpty ( videoPrimaryInfoRenderer ) ) {
876913 throw new ParsingException ("Could not find videoPrimaryInfoRenderer" );
877914 }
878915
@@ -894,7 +931,7 @@ private JsonObject getVideoSecondaryInfoRenderer() throws ParsingException {
894931 }
895932 }
896933
897- if (videoSecondaryInfoRenderer == null ) {
934+ if (isNullOrEmpty ( videoSecondaryInfoRenderer ) ) {
898935 throw new ParsingException ("Could not find videoSecondaryInfoRenderer" );
899936 }
900937
@@ -904,6 +941,7 @@ private JsonObject getVideoSecondaryInfoRenderer() throws ParsingException {
904941
905942 @ Nonnull
906943 private static String getVideoInfoUrl (final String id , final String sts ) {
944+ // TODO: Try parsing embedded_player_response first
907945 return "https://www.youtube.com/get_video_info?" + "video_id=" + id +
908946 "&eurl=https://youtube.googleapis.com/v/" + id +
909947 "&sts=" + sts + "&ps=default&gl=US&hl=en" ;
0 commit comments