Scraper de canales de YouTube hacia notas Markdown para base de conocimiento (Obsidian-ready), con plataforma web local. Engine + CLI (Workstream A): - Modular pipeline: discover/extract/parse/chapters/render/store + ratelimit - SQLite store con migración idempotente: FTS5 (transcript search), columnas de metadata enriquecida, tablas cookies_meta y scrape_jobs - Módulos: segments, cookies (Netscape vault), export (json/csv/srt/html), analysis (word freq/timeline/wordcloud), monitor (watch loop), pipeline - CLI Click group: search, export, audio, channels, watch, analyze, re-render - Fix del bug de scoping de cookies en cli.py Webapp local (Workstream B): - FastAPI backend: dashboard, channels, videos facetado, transcript, search FTS, analysis, scrape jobs con SSE, cookies drag-and-drop, exports, folders (abrir en OS), tools (re-render, formato) - SPA no-build (Alpine.js + Tailwind + Chart.js por CDN): 9 vistas, tema dark command-center con acento rojo→rosa, cookie vault drag-drop, consola de scrapeo con progreso live vía SSE Launcher + subagentes (Workstream C): - start-server.bat / stop-server.bat con auto port-scan + browser open - .opencode/agent/webapp-builder.md + .opencode/goals/webapp-build.md Tests: 38 pytest verdes. Sin funcionalidad de IA (enfoque data-mining).
9.6 KiB
AUDIT · Oportunidades de extensión
Análisis de features, comandos y opciones que se pueden construir sobre la infraestructura actual. Cada item incluye: valor, esfuerzo estimado, dependencias y comando propuesto.
Infraestructura disponible (lo que ya tenemos)
| Recurso | Estado | Reutilizable para |
|---|---|---|
yt-dlp instalado |
✅ v2026.7.4 | Audio/video download, thumbnails, metadata enriquecida |
| SQLite 3.49 con FTS5 | ✅ verificado | Búsqueda full-text sobre transcripciones |
| SQLite JSON1 | ✅ verificado | Queries estructuradas sobre metadatos |
| 33 transcripciones parseadas | ✅ en data/state.db |
Análisis, estadísticas, búsqueda |
| Markdown con frontmatter YAML | ✅ 842 KB en data/markdown/ |
Obsidian, Pandoc, static site generators |
| Pipeline modular | ✅ 8 módulos | Insertar nuevos pasos sin romper nada |
TIER 1 · Alto valor, bajo esfuerzo (1-3 h c/u)
1. search — Búsqueda full-text en transcripciones
yt-scraper search "vaporwave"
yt-scraper search "dragon ball" --channel UCmhcYyPg7fsxMzQsY0RJBjw
Qué hace: busca texto dentro de las transcripciones ya scrapeadas y devuelve vídeo + timestamp exacto.
Implementación:
- Nueva tabla
transcript_segments(video_id, start, text)poblada durante el scrape - Índice
USING fts5(text)sobre esa tabla - Comando
searchque haceSELECT ... WHERE transcript_segments MATCH ? - Esfuerzo: 1-2 h. Sin dependencias nuevas.
2. stats — Estadísticas del canal
yt-scraper stats
yt-scraper stats --channel UCmhcYyPg7fsxMzQsY0RJBjw
Qué muestra:
Nostal Vlad (@Nostal-Vlad)
Videos: 33 scrapeados / 37 totales
Duración total: 11.2 horas
Palabras totales: 89,432
Fecha rango: 2019-04-28 → 2026-07-26
Views promedio: 45,231
Likes promedio: 3,201
Top tags: videojuegos (12), 2000s (10), nostalgia (8)
Implementación: queries SQL agregadas + presentación con Rich tables.
- Esfuerzo: 1 h.
3. export — Export multi-formato
yt-scraper export --format json # un JSON con todo
yt-scraper export --format csv # CSV de metadatos
yt-scraper export --format srt # subtítulos SRT estándar
yt-scraper export --format html # galería navegable
Implementación:
- JSON: serializar
Store.get_all()+ leer transcripciones de los.md - CSV:
csv.writersobre metadatos - SRT: ya tenemos
{start, end, text}enSegment— conversión trivial - HTML: plantilla Jinja2 con tarjetas por vídeo (thumbnail + título + link)
- Esfuerzo: 2-3 h los 4 formatos.
4. clip — Extracción de segmento por timestamp
yt-scraper clip gOUyxFwWQqA --from 01:38 --to 03:20
Qué hace: devuelve el texto de la transcripción entre dos timestamps, listo para citar.
Implementación: cargar el .md, parsear segmentos, filtrar por rango.
- Esfuerzo: 30 min.
5. audio — Descarga de audio (podcast)
yt-scraper --channel "https://www.youtube.com/@Nostal-Vlad/videos" --download-audio
Qué hace: descarga el audio MP3 de cada vídeo junto a la transcripción.
Implementación: añadir a extract.py:
ydl_opts["format"] = "bestaudio/best"
ydl_opts["postprocessors"] = [{"key": "FFmpegExtractAudio", "preferredcodec": "mp3", "preferredquality": "128"}]
ydl_opts["outtmpl"] = str(output_dir / "%(title)s.%(ext)s")
Requiere ffmpeg instalado.
- Esfuerzo: 1 h.
6. re-render — Regenerar Markdown tras cambiar plantilla
yt-scraper re-render
Qué hace: re-procesa todos los .md usando la plantilla actual sin re-descargar nada de YouTube. Útil cuando cambias video.md.j2.
Implementación: guardar segments y chapters en SQLite (columnas JSON), o re-parsear los .md existentes.
- Esfuerzo: 1-2 h.
TIER 2 · Alto valor, esfuerzo medio (3-8 h c/u)
7. Multi-canal — Gestión de varios canales
yt-scraper channels add "https://www.youtube.com/@otro-canal"
yt-scraper channels list
yt-scraper --channel @nostal-vlad search "vaporwave"
yt-scraper --all-channels stats
Implementación: tabla channels ya existe; ampliar CLI con subcomandos channels add/list/remove. El Store ya soporta multi-canal (PK por channel_id).
- Esfuerzo: 3-4 h.
8. watch — Monitoreo de nuevos vídeos
yt-scraper watch --interval 6h
Qué hace: ejecuta discovery periódicamente, y si hay vídeos nuevos los procesa automáticamente.
Implementación: loop con time.sleep(interval) + discover_channel(). En Windows se puede dejar corriendo o usar Task Scheduler.
- Esfuerzo: 2-3 h.
9. Análisis de contenido
yt-scraper analyze --wordcloud
yt-scraper analyze --top-words 50
yt-scraper analyze --timeline "vaporwave"
Qué hace:
- Nube de palabras (matplotlib + wordcloud)
- Frecuencia de términos con gráfico
- Timeline: cuándo se mencionó un tema a lo largo del tiempo
Dependencias nuevas: matplotlib, wordcloud, nltk (o regex simple para español).
- Esfuerzo: 4-5 h.
10. thumbnails — Descarga masiva de miniaturas
yt-scraper thumbnails --size maxres
Implementación: ya tenemos thumbnail URL en el frontmatter. Un requests.get por vídeo + guardar en data/thumbnails/.
- Esfuerzo: 30 min.
11. Traducción de transcripciones
yt-scraper --channel @nostal-vlad --translate-to en
Qué hace: traduce cada transcripción al idioma especificado antes de renderizar el Markdown.
Opciones:
- Google Translate (gratis, vía
deep-translator): rápido, baja calidad - LLM (OpenAI/Anthropic): calidad alta, requiere API key
- Esfuerzo: 3-4 h (cualquier ruta).
TIER 3 · Features avanzadas (8+ h)
12. LLM Summaries — Resúmenes por vídeo
yt-scraper --channel @nostal-vlad --summarize
Qué hace: genera un resumen de 3-5 párrafos por vídeo usando un LLM. Se añade al Markdown como campo summary en el frontmatter.
Implementación:
- Nuevo módulo
summarize.py - Usa la transcripción completa como contexto
- Modelos: OpenAI
gpt-4o-mini($0.015 por vídeo de 20 min), Anthropic Claude Haiku, o modelo local conollama - Guardar resumen en SQLite para no re-ejecutar
- Esfuerzo: 4-6 h.
Dependencias: openai o anthropic o ollama (local, gratis).
13. Q&A / RAG — Preguntas sobre el canal
yt-scraper ask "¿Qué dijo Vlad sobre los juegos flash?"
Qué hace: busca en todas las transcripciones y responde con citas + timestamps exactos.
Implementación:
- RAG simple: FTS5 search → mandar top-K segmentos al LLM como contexto
- RAG con embeddings:
sentence-transformers→ ChromaDB/FAISS → recuperación semántica - Esfuerzo: RAG simple 4-5 h, con embeddings 8-10 h.
14. Extracción de entidades (NER)
yt-scraper analyze --entities
Qué hace: detecta personas, marcas, lugares, videojuegos mencionados a lo largo de todos los vídeos.
Output: tabla entities(video_id, type, name, count) → "Pokémon mencionado en 8 vídeos", "Sonic en 5 vídeos".
Implementación: spaCy (modelo es_core_news_sm) o LLM con prompt estructurado.
- Esfuerzo: 4-6 h.
15. Speaker diarization — Separación de hablantes
Qué hace: distingue "narrador" de "entrevistado" o "invitado" en la transcripción.
Implementación: el audit del Web Clipper ya documenta esto (groupBySpeaker en YoutubeExtractor). Se puede portar a Python o usar pyannote-audio.
- Esfuerzo: port del algoritmo 2-3 h; con modelo de audio 8+ h.
Matriz de prioridades
| # | Feature | Valor | Esfuerzo | ROI |
|---|---|---|---|---|
| 1 | search (FTS5) |
🔥🔥🔥 | 1-2 h | ⭐⭐⭐ |
| 2 | stats |
🔥🔥 | 1 h | ⭐⭐⭐ |
| 3 | export json/srt/html |
🔥🔥 | 2-3 h | ⭐⭐⭐ |
| 4 | clip |
🔥 | 30 min | ⭐⭐ |
| 5 | audio download |
🔥🔥 | 1 h | ⭐⭐⭐ |
| 6 | re-render |
🔥 | 1-2 h | ⭐⭐ |
| 7 | Multi-canal | 🔥🔥 | 3-4 h | ⭐⭐ |
| 8 | watch mode |
🔥🔥 | 2-3 h | ⭐⭐ |
| 9 | Análisis (wordcloud) | 🔥 | 4-5 h | ⭐ |
| 10 | thumbnails |
🔥 | 30 min | ⭐⭐⭐ |
| 11 | Traducción | 🔥🔥 | 3-4 h | ⭐⭐ |
| 12 | LLM summaries | 🔥🔥🔥 | 4-6 h | ⭐⭐⭐ |
| 13 | Q&A / RAG | 🔥🔥🔥 | 4-10 h | ⭐⭐ |
| 14 | NER (entidades) | 🔥 | 4-6 h | ⭐ |
| 15 | Speaker diarization | 🔥 | 2-8 h | ⭐ |
Dependencias Python adicionales por feature
# Tier 1 — sin dependencias nuevas (solo stdlib)
# search, stats, export, clip, re-render usan SQLite + Jinja2 ya instalados
# Tier 2
pip install matplotlib wordcloud # análisis / wordcloud
pip install deep-translator # traducción gratuita
# Tier 3
pip install openai # LLM summaries / Q&A
pip install sentence-transformers # embeddings para RAG semántico
pip install spacy && python -m spacy download es_core_news_sm # NER
pip install pyannote.audio # speaker diarization (requiere GPU idealmente)
# Audio download
# Requiere ffmpeg instalado en el sistema:
# winget install ffmpeg
# o: choco install ffmpeg
Comandos compuestos propuestos (pipelines)
# Pipeline completo: scrapear + buscar + extraer clip
yt-scraper --channel @nostal-vlad scrape
yt-scraper search "frutiger aero"
yt-scraper clip 8tMQMtIBfTE --from 02:15 --to 04:30 > clip.md
# Pipeline de análisis
yt-scraper stats > stats.txt
yt-scraper export --format html > index.html
yt-scraper analyze --top-words 30 > palabras.csv
# Pipeline LLM
yt-scraper --channel @nostal-vlad --summarize
yt-scraper ask "¿Qué opina Vlad sobre la cultura otaku?"