Skip to content

youtube.fetchExtended()#41

Merged
oskarrough merged 11 commits intoradio4000:mainfrom
oskarrough:feat/extended-fetch
Feb 8, 2026
Merged

youtube.fetchExtended()#41
oskarrough merged 11 commits intoradio4000:mainfrom
oskarrough:feat/extended-fetch

Conversation

@oskarrough
Copy link
Collaborator

WIP.

Two changes:

  1. The fetch method we have from YouTube includes title and duration e.g. the essentials, but it doesn't include the real song used in the video. This adds a new youtube.fetchExtended(url) function that scrapes the YouTube video page for this info. Same approach yt-dlp uses at the moment. It works, we then know the real song most of the time, but downside is that it's around 800ms vs 80ms for this request. This is why I split it into two methods, and it's not run by default via getMedia().

  2. Also deleted the SearchResult interface, and made author?optional in YouTubeResult. This way youtube.search() now returns YouTubeResult[] with payload: videoRenderer.

oskarrough and others added 8 commits February 7, 2026 12:18
Delete 7 exploration scripts and 1 oversized fixture from scripts/yt-probe/.
These were used to discover YouTube's watch page data structures during
development of fetchExtended(), but all useful logic is now in youtube.ts
with proper test coverage.

Keep yt-bench.ts (perf benchmarking) and yt-test-tracks.json (fixture),
moved up to scripts/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove id, slug, created_at, updated_at, and source fields —
only media_id and track metadata are needed for benchmarking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove extractMusicCard/extractDescHeader unit tests that just
assert against mocked JSON structures (circular — won't catch
YouTube changes). Replace with integration tests that hit live
YouTube across 3 video types: official music, Topic channel,
and non-music video.

Also unexport extractMusicCard/extractDescHeader since they're
internal implementation details.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both functions had identical panel traversal loops. Combine into
one extractWatchPageData() that walks the panels once and picks
up both music card and description header data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- YouTubeResult: basic fields from oEmbed (fast ~100ms)
- YouTubeExtendedResult: adds music metadata from watch page (slow ~900ms)
- Clarifies which fields come from which fetch method

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Make author optional in YouTubeResult
- youtube.search() now returns YouTubeResult[] instead of SearchResult[]
- Search results include payload (videoRenderer object)
- Remove redundant SearchResult type
- Update specs to reflect changes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
oskarrough and others added 3 commits February 8, 2026 12:52
- Add fetchExtended to providers section
- Note performance: ~100ms for basic fetch vs ~1s for extended
- Clarify extended includes music card data (song, artist, album)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Delete WatchPageData interface
- Internal functions return inferred types
- Public API (YouTubeExtendedResult) unchanged
- Less type duplication, cleaner code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@oskarrough oskarrough merged commit 123ff3b into radio4000:main Feb 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant