From 1dc286ce9f0e36faaa4d564634d6590b662c3950 Mon Sep 17 00:00:00 2001 From: vitya Date: Mon, 25 May 2026 13:37:40 +0300 Subject: [PATCH] feat(using-yt-tools): add yt-listen support (audio/FFT) v0.3.2 --- skills/using-yt-tools/SKILL.md | 43 ++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/skills/using-yt-tools/SKILL.md b/skills/using-yt-tools/SKILL.md index b9e62c1..ecccac5 100644 --- a/skills/using-yt-tools/SKILL.md +++ b/skills/using-yt-tools/SKILL.md @@ -1,16 +1,16 @@ --- name: using-yt-tools -version: 0.3.1 -description: Two flows for YouTube content. **Iterative-watch** (summary/exploration): transcript with [mm:ss] anchors → pick moments → extract frames. **Targeted-frames** (specific timestamps): extract frames directly, no transcript. Triggers: "что в ролике", "о чём видео", "video summary", "youtube transcript", "покажи кадр на N", или любой youtube.com URL. CLI в `~/projects/.common/lib/yt-tools/`. YouTube-only; для Vimeo/Twitch/local — другие тулзы. +version: 0.3.2 +description: Three flows for YouTube content. **Iterative-watch** (summary/exploration): transcript with [mm:ss] anchors → pick moments → extract frames. **Targeted-frames** (specific timestamps): extract frames directly, no transcript. **Audio-analysis** (music FFT): per timestamp spectrogram + numeric digest (BPM, key, chord progression, harmonic content) via `yt-listen`. Triggers: "что в ролике", "о чём видео", "video summary", "youtube transcript", "покажи кадр на N", "послушай момент N", "BPM/тональность видео", "спектрограмма", "listen to fragment", "analyze audio", или любой youtube.com URL. CLI в `~/projects/.common/lib/yt-tools/`. YouTube-only; для Vimeo/Twitch/local — другие тулзы. --- # using-yt-tools -Iterative-watching YouTube для агента: clean-markdown транскрипт с `[mm:ss]`-якорями → агент решает, какие моменты интересны → targeted frame extraction по таймкодам → агент видит кадры через `Read`. Альтернативный flow — если юзер уже назвал таймкоды, идём прямо за кадрами без транскрипта. +Iterative-watching YouTube для агента: clean-markdown транскрипт с `[mm:ss]`-якорями → агент решает, какие моменты интересны → targeted frame extraction по таймкодам → агент видит кадры через `Read`. Альтернативный flow — если юзер уже назвал таймкоды, идём прямо за кадрами без транскрипта. Для музыкальных URL — третий flow с FFT-анализом (BPM, key, chord progression, спектр) через `yt-listen`. ## When to use -Два различных flow, выбор по user intent: +Три различных flow, выбор по user intent: **Flow A — iterative-watch** (exploration / summary): - Юзер спрашивает что в ролике, хочет summary, хочет узнать о чём видео. @@ -22,7 +22,13 @@ Iterative-watching YouTube для агента: clean-markdown транскри - Шаги: extract frames at given timestamps → Read frames. - Trigger phrases: «покажи кадр на N», «посмотри момент N», «что показано на N», «show frame at N». -Оба flow предполагают, что `yt-tools` CLI установлен из `~/projects/.common/lib/yt-tools/` (project-local venv). Бинари могут не быть на PATH текущей сессии — это норма, особенно после свежего `winget install`. **Никогда не abort'ить по голому `Get-Command yt-frames` / `which yt-frames`** — сначала прогнать резолв (см. Prerequisites → Locating binaries). +**Flow C — audio-analysis** (music FFT): +- Юзер просит музыкальный разбор: BPM, тональность, гармония, chord progression, спектр, harmonic content. +- Шаги: `yt-listen URL --timestamps T1,T2,...` → per timestamp 3 артефакта (`clip.wav` + `spectrum.png` + `features.md`) → Read **обоих** (PNG vision + .md числа). +- Trigger phrases: «послушай момент N в », «какой BPM», «тональность видео», «гармония», «спектрограмма», «что в музыке на T», «listen to fragment», «analyze audio». +- Если есть captions — `yt-transcript` опциональный (контекст), но НЕ для lyrics-из-music (см. What NOT to do). + +Все три flow предполагают, что `yt-tools` CLI установлен из `~/projects/.common/lib/yt-tools/` (project-local venv). Бинари могут не быть на PATH текущей сессии — это норма, особенно после свежего `winget install`. **Никогда не abort'ить по голому `Get-Command yt-frames` / `which yt-frames`** — сначала прогнать резолв (см. Prerequisites → Locating binaries). ## Prerequisites @@ -30,12 +36,12 @@ Iterative-watching YouTube для агента: clean-markdown транскри Скил ничего не предполагает про активный PATH. **Step 0 каждого flow** — резолв путей для `yt-frames`/`yt-transcript` и `ffmpeg` (+ `yt-dlp`, поставляется в том же venv). Если резолвится через fallback — используй PATH-prepend в каждом вызове (см. Invoke pattern ниже). Abort'ить **только** если бинаря нет ни на PATH, ни в известных install-локациях. -**yt-tools CLI** (любая из локаций даёт все четыре: `yt-frames`, `yt-transcript`, `yt-watch`, `yt-tools` + бонусом `yt-dlp`): +**yt-tools CLI** (любая из локаций даёт все пять: `yt-frames`, `yt-transcript`, `yt-listen`, `yt-watch`, `yt-tools` + бонусом `yt-dlp`): -1. **PATH**: `Get-Command yt-frames` (pwsh) / `command -v yt-frames` (bash) +1. **PATH**: `Get-Command yt-frames` (pwsh) / `command -v yt-frames` (bash). Для Flow C — probe также `yt-listen` (присутствует с pyproject 0.2.0+; если только `yt-frames` находится, а `yt-listen` нет — машина на старом 0.1.x, нужен `pipx reinstall yt-tools` / pull + reinstall). 2. **pipx-shim** (recommended install — см. install-hint ниже): - - Windows: `~/.local/bin/yt-frames.exe` - - Linux/macOS: `~/.local/bin/yt-frames` + - Windows: `~/.local/bin/yt-frames.exe` (+ `yt-listen.exe`) + - Linux/macOS: `~/.local/bin/yt-frames` (+ `yt-listen`) 3. **Legacy project-venv** (для машин до миграции на pipx): - Windows: `~/projects/.common/lib/yt-tools/.venv/Scripts/yt-frames.exe` - Linux/macOS: `~/projects/.common/lib/yt-tools/.venv/bin/yt-frames` @@ -85,8 +91,9 @@ yt-frames --timestamps 1:23,4:56 |---|---|---| | A — iterative-watch | YouTube URL или bare 11-char video id | `--lang ru,en` для non-English subs; `--out PATH` | | B — targeted-frames | YouTube URL + timestamps (`mm:ss`, `h:mm:ss`, или bare seconds: `123` → 2:03) | `--no-cache-source` (stream вместо кеша source.mp4); `--out DIR` | +| C — audio-analysis | YouTube URL + timestamps (как у B) | `--duration 30s` (default 30s, lower bound для beat-tracking); `--mode interval --interval 60s` (bulk sampling); `--no-wav` / `--no-spectrogram` (default ON); `--linear` (STFT вместо mel); `--chroma` (bonus chromagram PNG); `--sample-rate 22050`; `--no-cache-source`; `--out DIR` | -Оба flow пишут в `/yt-cache//` по умолчанию. +Все три flow пишут в `/yt-cache//` по умолчанию (Flow C — в `audio/` поддиректорию). ## Steps @@ -120,6 +127,20 @@ Warnings и errors уходят в stderr (`warning: …`, `error: …`); stdout Без transcript fetch. Если потом юзер спросит «что говорилось в тот момент?», переключайся на Flow A на том же URL — `source.mp4` cache переиспользуется, повторного download нет. +### Flow C — audio-analysis + +``` +0. Резолв yt-listen + ffmpeg per Prerequisites → Locating binaries; собрать PATH-prepend если резолв через fallback +1. Parse timestamps (mm:ss / h:mm:ss / bare seconds — как у Flow B) +2. yt-listen --timestamps T1,T2,... → ./yt-cache//audio/{clip,spectrum,features}_TTTT.{wav,png,md} +3. Read **обоих** per timestamp: features_TTTT.md (числа — BPM, key, chord progression, spectral features, peak frequencies, harmonic/percussive split) + spectrum_TTTT.png (vision) +4. Reasoning по BPM/key/chord/spectral. Цитируй конкретные числа из features.md; spectrum-PNG — supplementary signal, не основной (см. What NOT to do) +``` + +Stdout-контракт `yt-listen` — одна строка `Wrote: ` per artifact (3 на каждый таймкод: wav, png, md), как у `yt-frames`. + +`source.mp4` cache переиспользуется между Flow A/B/C на одном URL — никаких повторных downloads. Default duration 30s (lower bound для beat-tracking); `--duration` override доступен. Для bulk-sampling музыкального ролика — `--mode interval --interval 60s` вместо явных таймкодов. + ## Failure modes Все failures abort cleanly; никогда не оставляй наполовину готовое состояние. @@ -157,3 +178,5 @@ Cache hygiene: `yt-tools cache list` показывает usage, `yt-tools cache - **Не пересказывай / не переводи transcript в свой ответ молча.** Артефакт — для твоего reasoning; цитируй с `[mm:ss]`-якорем когда приводишь пассаж. - **Не вызывай скил на non-YouTube URL.** Vimeo / Twitch / TikTok / local mp4 — out of scope. Бери другие тулзы (или yt-dlp напрямую). - **Не пиши результаты в произвольные пути.** По умолчанию `/yt-cache//`; явный `--out` только если юзер просил. +- **Не вызывай Whisper на смешанной музыке.** Юзер просит lyrics из музыкального ролика → это **не** `yt-listen`. Whisper на mixed music без source-separation = мусор (подтверждено arXiv 2506.15514). Скажи юзеру, что lyrics из music — отдельный pipeline (Demucs/Spleeter source-separation + Whisper поверх isolated vocals), out of scope текущего `yt-tools`. Не пытайся подсунуть `yt-transcript` как замену — YouTube auto-subs для музыки обычно нет, и `yt-listen` НЕ имеет Whisper-флага даже опционально. +- **Не интерпретируй `spectrum_*.png` без `features_*.md` в паре.** VLM-сигнал на audio спектрограммах ограничен (~50-60% accuracy на ESC-10, vs 72.5% human; Dixit et al. arXiv 2411.12058). Числовой digest из features.md — primary канал; spectrum-PNG — supplementary visual cue. Когда читаешь PNG — всегда читай и .md того же таймкода; цитируй BPM/key/chord/spectral из текстовых полей, не из «как выглядит картинка».