|
49 | 49 | import java.time.format.DateTimeFormatter; |
50 | 50 | import java.util.List; |
51 | 51 | import java.util.regex.Pattern; |
| 52 | +import java.util.stream.Collectors; |
52 | 53 |
|
53 | 54 | public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor { |
54 | 55 |
|
@@ -155,19 +156,24 @@ public long getDuration() throws ParsingException { |
155 | 156 | duration = videoInfo.getString("lengthSeconds"); |
156 | 157 |
|
157 | 158 | if (isNullOrEmpty(duration)) { |
158 | | - final JsonObject timeOverlay = videoInfo.getArray("thumbnailOverlays") |
| 159 | + final List<String> timeOverlays = videoInfo.getArray("thumbnailOverlays") |
159 | 160 | .stream() |
160 | 161 | .filter(JsonObject.class::isInstance) |
161 | 162 | .map(JsonObject.class::cast) |
162 | 163 | .filter(thumbnailOverlay -> |
163 | 164 | thumbnailOverlay.has("thumbnailOverlayTimeStatusRenderer")) |
164 | | - .findFirst() |
165 | | - .orElse(null); |
166 | | - |
167 | | - if (timeOverlay != null) { |
168 | | - duration = getTextFromObject( |
169 | | - timeOverlay.getObject("thumbnailOverlayTimeStatusRenderer") |
170 | | - .getObject("text")); |
| 165 | + .map(thumbnailOverlay -> getTextFromObject( |
| 166 | + thumbnailOverlay.getObject("thumbnailOverlayTimeStatusRenderer") |
| 167 | + .getObject("text"))) |
| 168 | + .filter(text -> !isNullOrEmpty(text)) |
| 169 | + .collect(Collectors.toList()); |
| 170 | + |
| 171 | + for (final String timeOverlayText : timeOverlays) { |
| 172 | + try { |
| 173 | + return YoutubeParsingHelper.parseDurationString(timeOverlayText); |
| 174 | + } catch (final ParsingException ex) { |
| 175 | + // try next |
| 176 | + } |
171 | 177 | } |
172 | 178 | } |
173 | 179 |
|
@@ -452,24 +458,21 @@ public boolean isShortFormContent() throws ParsingException { |
452 | 458 | } |
453 | 459 |
|
454 | 460 | if (!isShort) { |
455 | | - final JsonObject thumbnailTimeOverlay = videoInfo.getArray("thumbnailOverlays") |
456 | | - .stream() |
457 | | - .filter(JsonObject.class::isInstance) |
458 | | - .map(JsonObject.class::cast) |
459 | | - .filter(thumbnailOverlay -> thumbnailOverlay.has( |
460 | | - "thumbnailOverlayTimeStatusRenderer")) |
461 | | - .map(thumbnailOverlay -> thumbnailOverlay.getObject( |
462 | | - "thumbnailOverlayTimeStatusRenderer")) |
463 | | - .findFirst() |
464 | | - .orElse(null); |
465 | | - |
466 | | - if (!isNullOrEmpty(thumbnailTimeOverlay)) { |
467 | | - isShort = thumbnailTimeOverlay.getString("style", "") |
468 | | - .equalsIgnoreCase("SHORTS") |
469 | | - || thumbnailTimeOverlay.getObject("icon") |
470 | | - .getString("iconType", "") |
471 | | - .toLowerCase() |
472 | | - .contains("shorts"); |
| 461 | + if (videoInfo.has("thumbnailOverlays")) { |
| 462 | + isShort = videoInfo.getArray("thumbnailOverlays") |
| 463 | + .stream() |
| 464 | + .filter(JsonObject.class::isInstance) |
| 465 | + .map(JsonObject.class::cast) |
| 466 | + .filter(thumbnailOverlay -> thumbnailOverlay.has( |
| 467 | + "thumbnailOverlayTimeStatusRenderer")) |
| 468 | + .map(thumbnailOverlay -> thumbnailOverlay.getObject( |
| 469 | + "thumbnailOverlayTimeStatusRenderer")) |
| 470 | + .anyMatch(timeOverlay -> timeOverlay.getString("style", "") |
| 471 | + .equalsIgnoreCase("SHORTS") |
| 472 | + || timeOverlay.getObject("icon") |
| 473 | + .getString("iconType", "") |
| 474 | + .toLowerCase() |
| 475 | + .contains("shorts")); |
473 | 476 | } |
474 | 477 | } |
475 | 478 |
|
|
0 commit comments