From 8c1f0a0fbc4e37bcfd784dfcef76613da39f140c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 7 Apr 2026 11:38:19 +0000 Subject: [PATCH] docs(06-01): complete YouTube audio loading plan - Create 06-01-SUMMARY.md with full execution details - Update STATE.md: advance to plan 2, 90% progress, add decisions - Update ROADMAP.md: phase 6 showing 1/3 plans complete --- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 21 +++-- .planning/phases/06-ai-sync/06-01-SUMMARY.md | 91 ++++++++++++++++++++ 3 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 .planning/phases/06-ai-sync/06-01-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 95f3b41..9701dfb 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -126,7 +126,7 @@ Plans: **Plans**: 3 plans Plans: -- [ ] 06-01: YouTube loading — yt-dlp download to /app/shows/, SSE progress streaming, transport bar URL input +- [x] 06-01: YouTube loading — yt-dlp download to /app/shows/, SSE progress streaming, transport bar URL input - [ ] 06-02: Feature extraction + segmentation — onset/chroma/RMS extraction, structural segmentation API, colored section band overlay on waveform - [ ] 06-03: AI sync engine — heuristic block mapper + optional LLM generation, AI Sync panel UI, per-section fill @@ -158,5 +158,5 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 | 3. Communication Protocol | 3/3 | Complete | 2026-04-06 | | 4. Timeline Editor | 4/4 | Complete | 2026-04-06 | | 5. Live Show Execution | 4/4 | Complete | 2026-04-07 | -| 6. AI Sync | 0/3 | Not started | - | +| 6. AI Sync | 1/3 | In Progress| | | 7. Microcontroller Firmware | 0/3 | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 0fc1588..43bc977 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Completed 05-live-show-execution/05-04-PLAN.md -last_updated: "2026-04-07T10:41:51.205Z" +stopped_at: Completed 06-ai-sync/06-01-PLAN.md +last_updated: "2026-04-07T11:38:05.324Z" last_activity: 2026-04-07 progress: total_phases: 7 completed_phases: 5 - total_plans: 18 - completed_plans: 18 + total_plans: 21 + completed_plans: 19 percent: 0 --- @@ -21,12 +21,12 @@ progress: See: .planning/PROJECT.md (updated 2026-04-05) **Core value:** Load a song, build a synchronized light show, play it back live — with precise control over every effect on every device. -**Current focus:** Phase 05 — live-show-execution +**Current focus:** Phase 06 — ai-sync ## Current Position -Phase: 6 -Plan: Not started +Phase: 06 (ai-sync) — EXECUTING +Plan: 2 of 3 Status: Ready to execute Last activity: 2026-04-07 @@ -70,6 +70,7 @@ Progress: [░░░░░░░░░░] 0% | Phase 05-live-show-execution P02 | 20 | 2 tasks | 3 files | | Phase 05-live-show-execution P03 | 10 | 1 tasks | 1 files | | Phase 05-live-show-execution P04 | 1 | 1 tasks | 1 files | +| Phase 06-ai-sync P01 | 8 | 3 tasks | 6 files | ## Accumulated Context @@ -122,6 +123,8 @@ Recent decisions affecting current work: - [Phase 05-live-show-execution]: Space on button elements explicitly skipped — prevents double-toggle with native button click - [Phase 05-live-show-execution]: Ctrl+S uses GET-then-POST round-trip to save current server show state, not in-memory timeline - [Phase 05-live-show-execution]: Audio element event listeners are correct hook for mouse play/pause WS messages — fire for all triggers (button/keyboard/programmatic), idempotent with wireKeyboard() sends +- [Phase 06-ai-sync]: sys.executable -m yt_dlp used to avoid PATH issues in Docker container +- [Phase 06]: yt-dlp --newline flag required for line-by-line progress parsing ### Pending Todos @@ -135,8 +138,8 @@ None yet. ## Session Continuity -Last session: 2026-04-07T10:38:10.089Z -Stopped at: Completed 05-live-show-execution/05-04-PLAN.md +Last session: 2026-04-07T11:37:58.939Z +Stopped at: Completed 06-ai-sync/06-01-PLAN.md Resume file: None Next action: `/gsd:plan-phase 1` diff --git a/.planning/phases/06-ai-sync/06-01-SUMMARY.md b/.planning/phases/06-ai-sync/06-01-SUMMARY.md new file mode 100644 index 0000000..aea1a60 --- /dev/null +++ b/.planning/phases/06-ai-sync/06-01-SUMMARY.md @@ -0,0 +1,91 @@ +--- +phase: 06-ai-sync +plan: 01 +subsystem: audio-input +tags: [youtube, yt-dlp, sse, streaming, frontend, transport-bar] +dependency_graph: + requires: [] + provides: [youtube-audio-download, sse-progress-stream, yt-dlp-dependency] + affects: [lightsync/api/audio.py, lightsync/frontend] +tech_stack: + added: [yt-dlp>=2025.0.0, anthropic>=0.40.0] + patterns: [asyncio subprocess, SSE ReadableStream, terminal progress bar] +key_files: + created: [] + modified: + - pyproject.toml + - docker-compose.prod.yml + - lightsync/api/audio.py + - lightsync/frontend/index.html + - lightsync/frontend/app.js + - lightsync/frontend/style.css +decisions: + - "sys.executable -m yt_dlp used to avoid PATH issues in Docker" + - "--newline flag required for line-by-line progress parsing from yt-dlp" + - "yt_%(id)s.%(ext)s output template ensures predictable filenames" + - "ANTHROPIC_API_KEY wired with empty default so container starts without it" + - "Beat analysis runs post-download (same as upload path) for identical audio pipeline entry" +metrics: + duration: "~8 min" + completed: "2026-04-07" + tasks_completed: 3 + files_changed: 6 +requirements_satisfied: [AUD-02] +--- + +# Phase 06 Plan 01: YouTube Audio Loading via yt-dlp Summary + +**One-liner:** YouTube URL download via yt-dlp subprocess with SSE progress streaming, terminal-style block progress bar, and automatic audio pipeline entry after download. + +## What Was Built + +Added full YouTube audio loading capability to the LightSync transport bar: + +1. **Dependencies (Task 1):** Added `yt-dlp>=2025.0.0` and `anthropic>=0.40.0` to `pyproject.toml`. Wired `ANTHROPIC_API_KEY` env var (empty default) in `docker-compose.prod.yml`. Both packages are importable inside the running container. + +2. **Backend endpoint (Task 2):** New `POST /api/audio/fetch` endpoint in `lightsync/api/audio.py` that: + - Accepts `{url: string}` JSON body + - Spawns yt-dlp subprocess via `sys.executable -m yt_dlp` (avoids PATH issues in Docker) + - Parses progress with `PROGRESS_RE = re.compile(r'\[download\]\s+([\d.]+)%')` using `--newline` flag + - Streams SSE progress events with `media_type="text/event-stream"` + - Runs beat analysis on completion and caches in `app.state.beats` + - Returns `{type: "done", path, filename}` event on success + +3. **Frontend UI (Task 3):** Added to transport bar in `index.html`: + - Text input `#yt-url` with placeholder "YOUTUBE URL" + - `#btn-fetch` button + - `#yt-progress` span for terminal-style progress display + + In `app.js`: + - `fetchWithProgress()` function using fetch ReadableStream reader for SSE + - `renderProgressBar()` rendering `DOWNLOADING ████████░░░░░░░░░░░░ 42%` style + - FETCH button handler with D-02 disable-during-download + - Auto-load into `#player` after download (identical to upload pipeline) + + In `style.css`: `.yt-url-input` and `.yt-progress` styles using existing CSS variables, flat/monospace/no border-radius. + +## Commits + +| Task | Commit | Description | +|------|--------|-------------| +| 1 | `165cdb6` | feat(06-01): add yt-dlp and anthropic dependencies | +| 2 | `d58ea8c` | feat(06-01): add YouTube download endpoint with SSE progress streaming | +| 3 | `dca1cb8` | feat(06-01): add YouTube URL input with terminal progress bar | + +## Deviations from Plan + +None - plan executed exactly as written. + +## Known Stubs + +None - YouTube download is fully wired end-to-end. + +## Self-Check: PASSED + +- `pyproject.toml` contains `yt-dlp>=2025.0.0` and `anthropic>=0.40.0` +- `docker-compose.prod.yml` contains `ANTHROPIC_API_KEY` +- `lightsync/api/audio.py` contains `async def fetch_youtube`, `PROGRESS_RE`, `media_type="text/event-stream"`, `class YouTubeFetchRequest`, `analyze_async(filename)` +- `lightsync/frontend/index.html` contains `id="yt-url"`, `id="btn-fetch"`, `id="yt-progress"` +- `lightsync/frontend/app.js` contains `fetchWithProgress`, `renderProgressBar`, `/api/audio/fetch`, `urlInput.disabled = true`, `audio.src` +- `lightsync/frontend/style.css` contains `.yt-url-input`, `.yt-progress` +- All 3 task commits exist: `165cdb6`, `d58ea8c`, `dca1cb8`