PRD-039: Player¶
- Status: Draft
- Authors: Marko
- Target Release: v2.7 (Phase P1)
- Parent PRD:
docs/prd/PRD-035-learning-platform.md - Depends on: PRD-036 (segments, insights, entities, enclosure, playback state)
- Upstream: PRD-038 (Catalog) · Feeds: PRD-040 (Capture), PRD-041 (Consolidation)
- Related UX spec:
docs/uxs/UXS-011-consumer-learning-app.md(Editorial Bold; Player visual contract) - Related RFC:
docs/rfc/RFC-099-learning-platform-consumer-client.md(client behaviour, MVP slice) - Supersedes:
PRD-030-platform-player.md(deleted draft)
Summary¶
The Player is the primary value surface. It plays podcast audio streamed from the original host with real-time transcript synchronisation — the current spoken segment is highlighted and the transcript auto-scrolls; any line is tappable to seek. A collapsible Knowledge Panel surfaces the pipeline's artifacts inline (summary, entities, grounded insights, in-episode grounded search). A queue lets the user line up episodes — Spotify-grade — and queuing an unprocessed episode kicks off scrape-on-demand so it's ready by the time it's reached.
Background & Context¶
- Transcript-synced playback is the clearest differentiator from standard players: only a player backed by a structured pipeline can highlight the exact sentence being spoken and surface who-said-what, grounded in verbatim quotes + timestamps.
- The Knowledge Panel makes pipeline output visible without leaving the player. It is minimal and collapsed by default — one tap to reveal.
- Per Principle 4, audio comes from the original enclosure URL (PRD-036 FR4); we never serve a copy.
Goals¶
- Spotify-grade playback: queue, controls, speed, resume — fast and polished on mobile.
- Transcript-synced playback as the core, unmistakable differentiator.
- Surface insights, entities, and summary in the Knowledge Panel without cluttering playback.
- Grounded in-episode search (retrieval over transcript + insights; no request-time LLM, D6).
- Persist playback position for resume across sessions and devices.
- Degrade gracefully: full audio + transcript even without GIL/KG artifacts.
Non-Goals¶
- Not background/lock-screen audio with native media-session in v2.7 (north-star).
- Not a full GI/KG viewer — the Knowledge Panel is a minimal inline surface; deep graph exploration stays in the operator viewer (RFC-062).
- Not social (no comments, clip-sharing, reactions).
- Not transcript editing/correction.
- Not chunked playback before processing completes (deferred advanced mode).
Changed from the old draft: a queue is now in scope (Spotify vibe), and audio is bridged from the original host, never streamed from a stored copy.
Personas¶
Active listener (follow along, jump back), researcher (grounded in-episode search, jump-to-moment), casual listener (queue and play; never opens the panel).
User Stories¶
- As a listener, I can queue several episodes and have them play in order.
- As a listener, I can follow the transcript as it plays and tap any line to jump there.
- As a curious listener, I can see the entities and insights for this episode without leaving the player.
- As a researcher, I can search within the episode and jump to the exact grounded passages that answer my question.
- As a returning listener, I can resume where I left off — on any device.
Functional Requirements¶
FR1: Layout¶
- FR1.1: Full-viewport on mobile; two-column on desktop (transcript main + collapsible Knowledge Panel).
- FR1.2: Episode title + podcast name at the top.
- FR1.3: Back navigation returns to Catalog; playback continues where technically feasible (pause-on-navigate acceptable for v2.7).
FR2: Queue & playback controls¶
- FR2.1: Standard controls: play/pause, scrub with elapsed/total, skip-back 15s, skip-forward 30s.
- FR2.2: Speed selector: 0.75× / 1× / 1.25× / 1.5× / 2×.
- FR2.3: Queue: add/remove/reorder episodes; auto-advance to the next on completion; "play next" and "add to queue" actions from Catalog cards (PRD-038).
- FR2.4: Queuing an unprocessed episode triggers scrape-on-demand (PRD-036 FR5) and shows its progress in the queue; it becomes playable when Ready.
- FR2.5: Playback position auto-saves to
PUT /api/app/playback/{slug}every ~10s and on pause; restored viaGETon open. - FR2.6: A "Resume from X:XX" prompt appears for episodes with a saved position.
FR3: Transcript panel¶
- FR3.1: Full transcript as a scrollable list of
segments.jsonsegments. - FR3.2: The playing segment is highlighted and auto-scrolled into view; auto-scroll pauses on manual scroll and re-enables after ~5s idle.
- FR3.3: Tapping a segment seeks audio to its start.
- FR3.4: Segment timestamps shown on hover/tap (desktop) or always (mobile), muted.
- FR3.5: Speaker labels per segment when diarization present — canonical
person:{slug}(RFC-072) when available, else raw label. - FR3.6: No transcript → panel offers "Request processing" (audio-only mode still plays).
- FR3.7 (retrospective, shipped #1091): Grounded-quote highlighting — transcript segments
backing a grounded insight (matched by timeline) get a
●marker + underline; tapping one opens the Insights panel and centre-scrolls to that insight (the transcript↔insight bridge). - FR3.8 (retrospective, shipped #1091): Manual sync nudge — a
Sync −/+control lets the listener shift the transcript↔audio alignment to compensate for ad-insertion drift in the bridged stream (the played audio carries dynamic ads not in our transcribed copy). Persisted per episode.
FR4: Insights panel (collapsible; collapsed on mobile, open on wide desktop)¶
Retrospective (shipped #1091): the panel is titled "Insights" in the UI (matching the dock button + cards). Topics and People are merged into one compact, expandable "Topics & People" row; tapping a chip searches the corpus for that term (the originally-specified person→insight filter was dropped).
- FR4.1 Summary: 2–4 sentence episode summary, shown first when available.
- FR4.2 Topics & People (merged): KG topics + persons as chips in one compact, expandable row
(
+N …to reveal the rest). Tapping a chip navigates to corpus search for that term. (Epic 3 layers cluster-first ordering + entity cards on top — PRD-043.) - FR4.3 Insights: grounded GIL insights as cards — insight text, supporting quote (verbatim),
speaker if attributed, and a timestamp link that seeks on tap. A
●grounded marker distinguishes insights with a timestamped quote from ungrounded claims. Max 5; "Show all" expands. - FR4.5 Ask / find in this episode: a search input scoped to this episode. On submit, the backend runs hybrid retrieval (RFC-090) over the episode's segments + insights and returns the most relevant grounded passages — verbatim text, speaker, and a timestamp link that seeks on tap. No request-time LLM (D6): results are extractive grounded matches, not generated prose — nothing to hallucinate, no provider or credentials in the player. A generative-answer layer on top is a parked future option.
- FR4.6 Graceful degradation: each section is independently optional (no summary→hidden, no KG→Topics/Persons hidden, no GIL→Insights hidden, no transcript→in-episode search hidden). All absent → panel explains intelligence requires GIL/KG processing.
FR5: Capture entry points (→ PRD-040)¶
- FR5.1: A one-tap "highlight current moment" control during playback, and a highlight action on any transcript segment and any insight card. (Storage/behaviour defined in PRD-040.)
Data sources¶
| Panel section | Source | Required |
|---|---|---|
| Transcript | segments.json (PRD-036 FR3.3) |
Yes |
| Audio | original enclosure URL (PRD-036 FR4) | Yes |
| Summary | summary artifact / metadata | No |
| Topics / Persons | kg.json (+ bridge.json) |
No |
| Insights | gi.json (Insight + Quote + ABOUT) |
No |
| In-episode search | episode segments + insights (hybrid search index) | No |
API summary¶
All endpoints live under the consumer namespace /api/app/* (RFC-098), isolated from the operator
API. The paths below are the shipped Epic-1 surface — the Player MVP is fully served (no net-new
server endpoints required).
| Method | Path | Description |
|---|---|---|
GET |
/api/app/episodes/{slug}/segments |
Transcript sync (PRD-036) |
GET |
/api/app/episodes/{slug}/insights |
Knowledge Panel insights |
GET |
/api/app/episodes/{slug}/entities |
Knowledge Panel entities |
GET |
/api/app/episodes/{slug}/audio-source |
Original enclosure URL (PRD-036, RFC-100) |
GET/PUT |
/api/app/playback/{slug} |
Resume position |
GET/PUT |
/api/app/queue |
Queue read/update |
GET |
/api/app/episodes/{slug}/search |
Episode-scoped grounded retrieval (no LLM) |
Success Metrics¶
- The playing segment is highlighted and in view at all times with no perceptible lag.
- Tapping a line seeks within 0.5s of the segment start.
- Playback position restores correctly on re-open, including a different device.
- ≥1 grounded insight with a tappable timestamp is visible for any GIL-processed episode.
- In-episode search returns ranked grounded passages with jump-to-moment links within ~1s; no request-time LLM.
- Player is fully functional (audio + transcript) for episodes with no GIL/KG — no broken panels.
- Queue auto-advances; a queued unprocessed episode becomes playable after its scrape completes.
Dependencies¶
- PRD-036 (segments, insights, entities, enclosure, playback/queue state, scrape).
- The hybrid search index (RFC-090) over the corpus; in-episode search filters it to the episode.
Open Questions¶
- Native media-session / background audio (north-star; depends on app shell decision PRD-035 D1).
- Whether/when to add an optional generative-answer layer on top of retrieval (parked per D6; would reintroduce a request-time LLM and the CI-stub requirement).
References¶
docs/prd/PRD-035-learning-platform.md,PRD-038-catalog.md,PRD-040-capture.mddocs/rfc/RFC-049-grounded-insight-layer-core.md,RFC-055-knowledge-graph-layer-core.md,RFC-072-canonical-identity-layer-cross-layer-bridge.md