Files
urieljareth 621bbc5f5c feat: local content-mining platform for YouTube creator scraping
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).
2026-07-26 23:19:34 -06:00

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 search que hace SELECT ... 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.writer sobre metadatos
  • SRT: ya tenemos {start, end, text} en Segment — 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 con ollama
  • 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?"