fix(extractors): detect livestreams from the thumbnail time-status overlay - #5844
Open
mdbraber wants to merge 1 commit into
Open
fix(extractors): detect livestreams from the thumbnail time-status overlay#5844mdbraber wants to merge 1 commit into
mdbraber wants to merge 1 commit into
Conversation
…erlay
`VideoRendererParser` decides `liveNow` solely from a "LIVE" entry in
`videoRenderer.badges`. YouTube no longer always sends one: on the trending feed
`badges` is absent entirely, and the only live marker is the thumbnail's
time-status overlay, which carries `{"style": "LIVE", "text": "LIVE"}` where a
duration would otherwise be.
The result is that the list and detail endpoints contradict each other for the
same video id: `/api/v1/trending` reports `liveNow: false` while
`/api/v1/videos/<id>` reports `liveNow: true`. This is especially visible because
trending *is* the livestreams feed now (`fetch_trending` browses the livestreams
channel since YouTube removed the aggregated trending page, iv-org#5397), so nearly
every trending item is affected. Measured 14 of 15 before, 0 of 15 after.
Read the overlay as a second source for the LiveNow badge, keeping the existing
`badges` parsing unchanged. `length_seconds` deliberately needs no equivalent
change: the overlay text is "LIVE", which `decode_length_seconds` already reduces
to 0, correct for a stream with no fixed duration.
AI disclosure, per AI_POLICY.md: this patch was written with AI assistance.
Exact model: Claude Opus 5, model ID `claude-opus-5[1m]`. Tool used to interact
with it: Claude Code, Anthropic's agentic CLI. The change was verified against a
live patched instance (see the PR for the measurements) and is running in
production on the submitter's instance. Submitted by and the responsibility of
@mdbraber.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the InnerTube VideoRendererParser so liveNow can be detected from the thumbnail time-status overlay when YouTube omits the "LIVE" metadata badge (notably on the trending/livestreams feed), preventing list and detail endpoints from disagreeing for the same video.
Changes:
- Detect
LiveNowfromthumbnailOverlays[].thumbnailOverlayTimeStatusRenderer.style == "LIVE"as an additional signal alongside existing badge parsing. - Add explanatory in-code context for why the overlay check is necessary.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+160
to
+163
| # On the trending feed — which is the livestreams feed since YouTube | ||
| # removed the aggregated trending page — `badges` is absent altogether and | ||
| # the only marker is the thumbnail's time-status overlay, which reads | ||
| # `{"style": "LIVE", "text": "LIVE"}` in place of a duration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VideoRendererParserdecidesliveNowsolely from a"LIVE"entry invideoRenderer.badges. YouTube no longer always sends one: on the trending feedbadgesis absent entirely, and the only live marker is the thumbnail's time-status overlay, which carries{"style": "LIVE", "text": "LIVE"}where a duration would otherwise be.The result is that the list and detail endpoints contradict each other for the same video id.
This is especially visible because trending is the livestreams feed now —
fetch_trendingbrowses the livestreams channel because YouTube removed the aggregated trending page (#5397) — so in practice nearly every trending item is affected. It also affects Invidious' own web UI, which renders the sameliveNow.Reproduction
Against an instance at
9d1291a0, region NL:14 of 15 trending items disagreed with their own detail endpoint. After the patch, 0 of 15.
The raw InnerTube payload for those items shows why — no
badgeskey at all:{ "videoId": "BRha0tJtI8s", "badges": null, "lengthText": null, "thumbnailOverlays": [ { "thumbnailOverlayTimeStatusRenderer": { "style": "LIVE", "text": { "simpleText": "LIVE" } } } ], "viewCountText": { "simpleText": "6,091 watching" } }Notes for reviewers
badgesparsing is untouched; the overlay is read as an additional source, soliveNowstill comes from a"LIVE"badge wherever YouTube sends one.length_secondsdeliberately needs no equivalent change: the overlay text is"LIVE", whichdecode_length_secondsalready reduces to0— correct for a stream with no fixed duration./api/v1/videos.crystal tool format --checkclean.feat(api): expose isShort on list items). Both inserta
thumbnailOverlaysread immediately after thebadgesloop inVideoRendererParser. Each branch applies cleanly tomasteron its own, butwhichever merges second will need a one-hunk rebase — happy to do that whenever
you like. They are independent changes, so they are offered separately rather
than bundled.
AI disclosure (per
AI_POLICY.md)This patch was written with AI assistance.
claude-opus-5[1m]How it was checked, stated precisely so you can judge it: the JSON path was not guessed — the raw InnerTube
browsepayload was fetched and inspected to find where the live marker had moved. The patch was then built, deployed to a live instance, and the before/after numbers above were measured on live data, including the false-positive check across three other endpoints. It is running in production on my instance.I am the submitter and, per the policy, solely responsible for this change. Happy to run any further test you would like before merge.