mirror of
https://github.com/iv-org/invidious.git
synced 2026-08-16 21:10:53 -05:00
fix(extractors): detect livestreams from the thumbnail time-status overlay
`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, #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.
This commit is contained in:
parent
9d1291a0b8
commit
250438f287
@ -156,6 +156,22 @@ private module Parsers
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A livestream no longer necessarily carries a "LIVE" entry in `badges`.
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# Without this, every item on that feed is serialised as
|
||||||
|
# `liveNow: false`, directly contradicting `/api/v1/videos` for the same
|
||||||
|
# video id. (`length_seconds` needs no equivalent fix: the overlay text is
|
||||||
|
# "LIVE", which `decode_length_seconds` already reduces to 0 — correct for
|
||||||
|
# a stream with no fixed duration.)
|
||||||
|
is_live_overlay = item_contents["thumbnailOverlays"]?.try &.as_a.any? do |overlay|
|
||||||
|
overlay.dig?("thumbnailOverlayTimeStatusRenderer", "style").try &.as_s == "LIVE"
|
||||||
|
end
|
||||||
|
badges |= VideoBadges::LiveNow if is_live_overlay
|
||||||
|
|
||||||
SearchVideo.new({
|
SearchVideo.new({
|
||||||
title: title,
|
title: title,
|
||||||
id: video_id,
|
id: video_id,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user