[YouTube] Fix duration and live stream display in related videos#1478
Conversation
…ts and improve Shorts detection
- 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
Tests cover: normal video with duration badge, video without duration badge (Shorts), and live stream. Mocks added for all three cases. Update disabled testMoreRelatedItems comment to reflect the fix.
|
TobiGr
left a comment
There was a problem hiding this comment.
Thank you! Just a small question.
| if (!input.matches(".*\\d.*") && !input.equalsIgnoreCase("SHORTS")) { | ||
| throw new ParsingException("Error duration string contains no digits: " + input); | ||
| } | ||
|
|
There was a problem hiding this comment.
I do not understand this change. Why exclude shorts here? If SHORTS is passed, it will fail in convertDurationToInt.
There was a problem hiding this comment.
YouTube does something special with shorts in certain places, instead of showing the numeric duration in the corner of the thumbnail, it simply shows the word SHORTS
SHORTS does not actually fail in convertDurationToInt, and that is precisely why the check exists.
Without the !input.equalsIgnoreCase("SHORTS") guard: parseDurationString("SHORTS") would hit this line first
if (!input.matches(".*\\d.*")) {
throw new ParsingException("Error duration string contains no digits: " + input);
}
It would throw immediately, never reaching convertDurationToInt at all.
The check is not there to exclude shorts, but to allow them thrugh so that the downstream fallback (returning 0) can handle the case where YouTube sends SHORTS instead of an actual timestamp



Two bugs in YoutubeStreamInfoItemLockupExtractor caused related/suggested videos to show wrong duration badges:
"00:00" on Shorts and videos without a duration badge
getDuration() threw ParsingException when no thumbnailBottomOverlayViewModel overlay was found. StreamInfoItemsCollector catches that exception and leaves duration at the Java default of 0, which the app renders as "00:00". Fixed by returning -1 (the established contract for unknown duration) instad of throwing also added a null guard before .matches() to prevent NPE on badges with no text field.
Live streams showing 00:00 on duration
determineStreamType() only checked thumbnailOverlayBadgeViewModel.thumbnailBadges for the live badge style. In the lockup format, YouTube places the live badge inside thumbnailBottomOverlayViewModel.badges — the same overlay used for duration text. So live streams were returned as VIDEO_STREAM, isLive() was false, and the app never reached the isLiveStream() branch that renders "LIVE". Fixed by adding a second check for thumbnailBottomOverlayViewModel.badges[].thumbnailBadgeViewModel.badgeStyle == THUMBNAIL_OVERLAY_BADGE_STYLE_LIVE