1818
1919package org .schabi .newpipe .extractor .services .youtube .extractors ;
2020
21- import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getTextFromObject ;
22- import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getThumbnailsFromInfoItem ;
23- import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getImagesFromThumbnailsArray ;
24- import static org .schabi .newpipe .extractor .utils .Utils .isNullOrEmpty ;
25-
2621import com .grack .nanojson .JsonArray ;
2722import com .grack .nanojson .JsonObject ;
28-
2923import org .schabi .newpipe .extractor .Image ;
3024import org .schabi .newpipe .extractor .exceptions .ParsingException ;
3125import org .schabi .newpipe .extractor .localization .DateWrapper ;
3226import org .schabi .newpipe .extractor .localization .TimeAgoParser ;
3327import org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper ;
3428import org .schabi .newpipe .extractor .services .youtube .linkHandler .YoutubeStreamLinkHandlerFactory ;
29+ import org .schabi .newpipe .extractor .stream .ContentAvailability ;
3530import org .schabi .newpipe .extractor .stream .StreamInfoItemExtractor ;
3631import org .schabi .newpipe .extractor .stream .StreamType ;
37- import org .schabi .newpipe .extractor .stream .ContentAvailability ;
3832import org .schabi .newpipe .extractor .utils .JsonUtils ;
3933import org .schabi .newpipe .extractor .utils .Parser ;
4034import org .schabi .newpipe .extractor .utils .Utils ;
4135
4236import javax .annotation .Nonnull ;
4337import javax .annotation .Nullable ;
44-
4538import java .time .Instant ;
4639import java .time .LocalDateTime ;
4740import java .time .ZoneId ;
4841import java .time .format .DateTimeFormatter ;
4942import java .util .List ;
5043import java .util .Optional ;
5144import java .util .regex .Pattern ;
52- import java .util .stream .Collectors ;
45+
46+ import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getImagesFromThumbnailsArray ;
47+ import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getTextFromObject ;
48+ import static org .schabi .newpipe .extractor .services .youtube .YoutubeParsingHelper .getThumbnailsFromInfoItem ;
49+ import static org .schabi .newpipe .extractor .utils .Utils .isNullOrEmpty ;
5350
5451public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
5552
@@ -132,15 +129,9 @@ public String getUrl() throws ParsingException {
132129 @ Override
133130 public String getName () throws ParsingException {
134131 final JsonObject title = videoInfo .getObject ("title" );
135- final String name = getTextFromObject (title );
136- if (!isNullOrEmpty (name )) {
137- return name ;
138- }
139- // Videos can have no title, e.g. https://www.youtube.com/watch?v=nc1kN8ZSfGQ
140- if (!isNullOrEmpty (title ) && !title .has ("runs" )) {
141- return "" ;
142- }
143- throw new ParsingException ("Could not get name" );
132+ return getTextFromObject (title )
133+ .or (() -> Optional .ofNullable (!title .has ("runs" ) ? "" : null ))
134+ .orElseThrow (() -> new ParsingException ("Could not get name" ));
144135 }
145136
146137 @ Override
@@ -149,45 +140,28 @@ public long getDuration() throws ParsingException {
149140 return -1 ;
150141 }
151142
152- String duration = getTextFromObject (videoInfo .getObject ("lengthText" ));
153-
154- if (isNullOrEmpty (duration )) {
155- // Available in playlists for videos
156- duration = videoInfo .getString ("lengthSeconds" );
157-
158- if (isNullOrEmpty (duration )) {
159- final List <String > timeOverlays = videoInfo .getArray ("thumbnailOverlays" )
160- .stream ()
161- .filter (JsonObject .class ::isInstance )
162- .map (JsonObject .class ::cast )
163- .filter (thumbnailOverlay ->
164- thumbnailOverlay .has ("thumbnailOverlayTimeStatusRenderer" ))
165- .map (thumbnailOverlay -> getTextFromObject (
166- thumbnailOverlay .getObject ("thumbnailOverlayTimeStatusRenderer" )
167- .getObject ("text" )))
143+ return getTextFromObject (videoInfo .getObject ("lengthText" ))
144+ .or (() -> Optional .ofNullable (videoInfo .getString ("lengthSeconds" )))
145+ .or (() -> videoInfo .getArray ("thumbnailOverlays" )
146+ .streamAsJsonObjects ()
147+ .map (thumbnailOverlay -> {
148+ final var thumbnailRendererText = thumbnailOverlay
149+ .getObject ("thumbnailOverlayTimeStatusRenderer" )
150+ .getObject ("text" );
151+ return getTextFromObject (thumbnailRendererText ).orElse (null );
152+ })
168153 .filter (text -> !isNullOrEmpty (text ))
169- .collect (Collectors .toList ());
170-
171- for (final String timeOverlayText : timeOverlays ) {
154+ .findFirst ())
155+ .map (duration -> {
172156 try {
173- return YoutubeParsingHelper .parseDurationString (timeOverlayText );
174- } catch (final ParsingException ex ) {
175- // try next
157+ return YoutubeParsingHelper .parseDurationString (duration );
158+ } catch (final ParsingException e ) {
159+ return null ;
176160 }
177- }
178- }
179-
180- if (isNullOrEmpty (duration )) {
181- if (isPremiere ()) {
182- // Premieres can be livestreams, so the duration is not available in this
183- // case
184- return -1 ;
185- }
186-
187- throw new ParsingException ("Could not get duration" );
188- }
189-
190- return YoutubeParsingHelper .parseDurationString (duration );
161+ })
162+ // Premieres can be livestreams, so the duration is not available in this case
163+ .or (() -> Optional .ofNullable (isPremiere () ? -1 : null ))
164+ .orElseThrow (() -> new ParsingException ("Could not get duration" ));
191165 }
192166
193167 @ Override
@@ -455,7 +429,7 @@ public boolean isShortFormContent() throws ParsingException {
455429 }
456430 }
457431
458- private boolean isMembersOnly () throws ParsingException {
432+ private boolean isMembersOnly () {
459433 return videoInfo .getArray ("badges" )
460434 .stream ()
461435 .filter (JsonObject .class ::isInstance )
@@ -467,7 +441,7 @@ private boolean isMembersOnly() throws ParsingException {
467441
468442 @ Nonnull
469443 @ Override
470- public ContentAvailability getContentAvailability () throws ParsingException {
444+ public ContentAvailability getContentAvailability () {
471445 if (isPremiere ()) {
472446 return ContentAvailability .UPCOMING ;
473447 }
0 commit comments