Skip to content

Commit 29bafb7

Browse files
committed
Fix duration and live stream detection in lockup extractor
- getDuration() returns -1 instead of throwing when no duration badge is present (e.g. Shorts in related section) - Add null guard before String.matches() to avoid NPE on missing badge text - determineStreamType() now also checks thumbnailBottomOverlayViewModel badges for the live style, so live streams in related videos are correctly identified as LIVE_STREAM instead of VIDEO_STREAM - Update Javadoc to reflect Shorts behaviour
1 parent 8e6e0ed commit 29bafb7

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,22 @@ public StreamType getStreamType() throws ParsingException {
7777
}
7878

7979
private StreamType determineStreamType() throws ParsingException {
80-
if (JsonUtils.getArray(lockupViewModel, "contentImage.thumbnailViewModel.overlays")
81-
.streamAsJsonObjects()
80+
final JsonArray overlays = JsonUtils.getArray(lockupViewModel,
81+
"contentImage.thumbnailViewModel.overlays");
82+
83+
// thumbnailOverlayBadgeViewModel path (legacy/alternate overlay structure)
84+
if (overlays.streamAsJsonObjects()
8285
.flatMap(overlay -> overlay
8386
.getObject("thumbnailOverlayBadgeViewModel")
8487
.getArray("thumbnailBadges")
8588
.streamAsJsonObjects())
8689
.map(thumbnailBadge -> thumbnailBadge.getObject("thumbnailBadgeViewModel"))
87-
.anyMatch(thumbnailBadgeViewModel -> {
88-
if ("THUMBNAIL_OVERLAY_BADGE_STYLE_LIVE".equals(
89-
thumbnailBadgeViewModel.getString("badgeStyle"))) {
90+
.anyMatch(vm -> {
91+
if ("THUMBNAIL_OVERLAY_BADGE_STYLE_LIVE".equals(vm.getString("badgeStyle"))) {
9092
return true;
9193
}
92-
9394
// Fallback: Check if there is a live icon
94-
return thumbnailBadgeViewModel
95-
.getObject("icon")
95+
return vm.getObject("icon")
9696
.getArray("sources")
9797
.streamAsJsonObjects()
9898
.map(source -> source
@@ -103,6 +103,18 @@ private StreamType determineStreamType() throws ParsingException {
103103
return StreamType.LIVE_STREAM;
104104
}
105105

106+
// thumbnailBottomOverlayViewModel path (used in lockup format for both duration and live)
107+
if (overlays.streamAsJsonObjects()
108+
.flatMap(overlay -> overlay
109+
.getObject("thumbnailBottomOverlayViewModel")
110+
.getArray("badges")
111+
.streamAsJsonObjects())
112+
.map(badge -> badge.getObject("thumbnailBadgeViewModel"))
113+
.anyMatch(vm -> "THUMBNAIL_OVERLAY_BADGE_STYLE_LIVE".equals(
114+
vm.getString("badgeStyle")))) {
115+
return StreamType.LIVE_STREAM;
116+
}
117+
106118
return StreamType.VIDEO_STREAM;
107119
}
108120

0 commit comments

Comments
 (0)