Skip to content

feat(player,genre-tree): add YouTube-backed playback for reference tracks - #30

Merged
Andreas-Garcia merged 6 commits into
mainfrom
feature/youtube-track-playback
Aug 20, 2026
Merged

feat(player,genre-tree): add YouTube-backed playback for reference tracks#30
Andreas-Garcia merged 6 commits into
mainfrom
feature/youtube-track-playback

Conversation

@Andreas-Garcia

Copy link
Copy Markdown
Member

Summary

  • grow-the-music-tree-api has no self-hosted audio storage, so reference-tree track playback is moving to embedded YouTube videos instead of downloaded audio files.
  • Extends the shared player and genre-tree modules to support both playback kinds without forking the logic into grow-the-music-tree-frontend.

Changes

  • Player: PlayerTrack is now a discriminated union (AudioPlayerTrack | YoutubePlayerTrack) instead of a single audio-only shape.
  • New MediaController interface (AudioMediaController / YoutubeMediaController) unifies play/pause/seek/volume across both kinds — PlayerContext no longer branches on track kind for playback control.
  • PlayerTrackObject.audioElement is replaced by PlayerTrackObject.mediaController — a breaking change for consumers reading the audio element directly (hear-the-music-tree-frontend needs a mechanical rename, tracked separately).
  • YouTube tracks play through the YouTube IFrame Player API, lazy-loaded once per page (loadYoutubeIframeApi), mounted into a new <PlayerVideoSurface /> component consumers render wherever the video should appear.
  • genre-tree: TrackDetailedSchema is now a real discriminated union (UploadedTrackDetailed | YoutubeTrackDetailed), each tagged with a kind field stamped via .transform() on the parsed output (neither backend sends kind on the wire — each route only ever serves one track kind).
  • UploadedTrackDetailedSchema keeps relativeUrl/file required; the new YoutubeTrackDetailedSchema requires youtubeVideoId and has no file fields.
  • Upload-only surfaces (useUploadTrack, useUpdateUploadedTrack, UploadedTrackEditionPopup, useTrackEdition) are typed against UploadedTrackDetailed specifically; list/playback surfaces stay on the generic TrackDetailed union.
  • TrackItem gates its edit affordance on track.kind === "uploaded", since grow-the-music-tree-api's YoutubeTrackViewSet has no update route.
  • Renamed playlist-relation fields to match grow-the-music-tree-api's UploadedTrackTrack rename: .uploadedTrack.track, .uploadedTrackPlaylistRelations.trackPlaylistRelations, .uploadedTracksCount/.uploadedTracksArchivedCount.tracksCount/.tracksArchivedCount, .uploadedTracks.tracks. hear-the-music-tree doesn't consume the criteria/criteria-playlist schemas, so this only affects grow-the-music-tree-frontend.
  • libraryEndpoints.reference now exposes .youtube (list/detail/delete only) instead of .uploaded; libraryEndpoints.me.uploaded (hear-the-music-tree's real uploaded-audio flow) is unchanged.

Test plan

  • CI: lint/build/test on this PR.
  • Manual sanity check that hear-the-music-tree-frontend still typechecks/builds against the extended types once its companion mediaController rename branch is applied (audio-only code path is otherwise untouched).

…adedTrack/YoutubeTrack discriminated union

gtmt-api has no self-hosted audio storage, so reference-tree tracks now
play as embedded YouTube videos instead. `PlayerTrack` is a discriminated
union (`AudioPlayerTrack` | `YoutubePlayerTrack`) driven through a new
`MediaController` interface (`AudioMediaController` / `YoutubeMediaController`),
so play/pause/seek code no longer branches on track kind. YouTube tracks
play through the YouTube IFrame Player API, lazy-loaded once per page and
mounted into a new `<PlayerVideoSurface />` component.

`TrackDetailedSchema` becomes a real union (`UploadedTrackDetailed` |
`YoutubeTrackDetailed`), each stamped with a `kind` field, replacing the
old flat schema. `libraryEndpoints.reference` now exposes `.youtube`
(list/detail/delete, mirroring gtmt-api's `YoutubeTrackViewSet`) instead
of `.uploaded`. `TrackItem`'s edit affordance is gated on
`kind === "uploaded"`, matching gtmt-api having no update route for
YouTube tracks.

Renamed the playlist-relation fields that mirror gtmt-api's
`UploadedTrack` → `Track` rename: `.uploadedTrack` → `.track`,
`.uploadedTrackPlaylistRelations` → `.trackPlaylistRelations`,
`.uploadedTracksCount`/`.uploadedTracksArchivedCount` →
`.tracksCount`/`.tracksArchivedCount`, `.uploadedTracks` → `.tracks`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app-kit-playground Ready Ready Preview Aug 20, 2026 9:27am

grow-the-music-tree-api removed its redundant reference/ route prefix
(every route lived under it with no unscoped counterpart); mirror that
here so these endpoint builders keep matching the real backend paths.
…erized builder

Matches the makeXEndpoints(prefix) pattern already used by library/uploaded
and library/youtube, instead of duplicating the me/reference shape by hand.
Comments should describe current behavior, not where code was moved
from or what a consuming app used to hardcode.
…ationAction

Rename should behave identically across consumers, not be an optional
no-op if omitted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…yground

parseWithLog/useQueryWithParse/useValidatedMutation typed their schema
param as z.ZodType<T> (Input defaults to Output), which breaks for any
.transform()-based schema whose input lacks a synthetically-stamped
field (e.g. the kind discriminant on Uploaded/YoutubeTrackDetailed).
Widen Input to unknown since callers only rely on the parsed Output type.

apps/playground was still on the pre-YouTube-migration uploaded/download
track API and missing the now-required handleGenreRenameAction prop,
previously masked by the package-level build failure above.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Andreas-Garcia
Andreas-Garcia merged commit 90056e9 into main Aug 20, 2026
4 checks passed
@Andreas-Garcia
Andreas-Garcia deleted the feature/youtube-track-playback branch August 20, 2026 09:39
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