Files
urieljareth 450aee216d docs: documentacion completa para humanos y agentes IA
- README reescrito: ejemplos CLI corregidos (flags van en el subcomando scrape),
  webapp+doctor documentados, requisitos por OS, cookies, datos generados, migracion de maquina
- CLAUDE.md actualizado: conteo de tests, refs de linea reparadas, scripts nuevos,
  checklist de actualizacion de docs
- AGENTS.md nuevo: entrada estandar para cualquier agente de codigo (mapa de modulos,
  comandos, reglas de oro, punteros a docs)
- docs/GETTING-STARTED.md: de cero a webapp por OS con troubleshooting
- docs/CONFIG.md: referencia completa de las ~25 claves de config
- docs/COOKIES.md: adquisicion, import (web/navegador/CLI), rotacion y seguridad
- docs/backlog.md reemplaza OPPORTUNITIES.md (distilado: shipped vs pendiente)
- auditorias movidas a docs/audits/ y CLIPPER-COMPARISON-AUDIT.md versionado
2026-09-10 00:32:32 -06:00

6.5 KiB
Raw Permalink Blame History

Referencia de configuración (config.yaml)

config.yaml es tu configuración privada (gitignored). La plantilla versionada config.example.yaml documenta todas las claves y es el punto de partida (cp config.example.yaml config.yaml). Todas las rutas del archivo se resuelven relativas al CWD — ejecuta siempre desde la raíz del repo.

Los defaults que siguen son los de config.example.yaml (entre paréntesis, cuando difiere, el default del código en src/yt_scraper/config.py).

Bloque raíz — canal, idiomas y filtros

Clave Tipo Default Qué afecta
channel_url str "https://www.youtube.com/@Nostal-Vlad/videos" Canal por defecto de yt-scraper scrape / webapp. Se ignora si pasas --channel/-c. Acepta URL completa, /channel/UC... o handle
languages dict | list {es: any, es-419: any, en: any} Idiomas de subtítulos aceptables y su modo (ver abajo). Forma legacy: lista ["es","en"] — todos con el modo de prefer_manual; evítala, un canal solo-auto quedaría en no_subtitles
prefer_manual bool true En modo any: prueba subtítulos manuales antes que los automáticos
include_shorts bool false Descubrir/procesar Shorts. En CLI: --include-shorts / --no-shorts
include_live bool true Procesar directos. En CLI: --no-live
min_duration_sec int 30 (código: 0) Duración mínima del vídeo en segundos; filtra en discovery

Modos por idioma de languages:

Valor Significado
manual Solo subtítulos subidos por el creador; si solo hay automáticos → no_subtitles
auto Solo subtítulos automáticos (ASR)
any Manuales primero (según prefer_manual), automáticos como fallback. Recomendado

Nota: languages es una preferencia entre idiomas que sabes leer, no una orden de traducir. El idioma hablado del vídeo siempre gana si está en la lista; nunca se guarda una traducción automática si existe el transcript original.

Bloque delay — pacing y rate-limit

YouTube no publica límites; el techo práctico conocido (wiki de yt-dlp) es ~300 vídeos/hora en sesión sin cuenta. Estos valores apuntan por debajo. Con los defaults conservadores, una tirada real cuesta del orden de 12–13 s por vídeo (~270 vídeos/hora).

Clave Tipo Default Qué afecta
min_seconds float 1.5 Pausa aleatoria mínima entre vídeos (el gap real se sortea entre min y max)
max_seconds float 3.5 Pausa aleatoria máxima entre vídeos
backoff_base float 2.0 Backoff tras un rate-limit: min(base * 2**n + jitter, cap), con n = fallos consecutivos
backoff_cap float 60.0 Techo del backoff en segundos
throttle_threshold int 3 Rate-limits consecutivos que hacen parar la tirada (circuit breaker). Lo no procesado queda pending y es recuperable
min_request_interval float 0.0 (example) Separación mínima entre cualquier dos peticiones a YouTube del proceso (Pacer global, incluye los /api/tools/* fuera del job runner). 0 = desactivado. Es la única palanca que actúa en todas partes a la vez
audio_rate_limit int 0 Techo de bytes/segundo para descargas de audio (ratelimit de yt-dlp). 0 = ilimitado

Referencia práctica: la config real del autor usa min_request_interval: 2.5 para ser aún más conservador cuando la webapp y el CLI conviven.

Bloque yt_dlp — reintentos y timeouts

Clave Tipo Default Qué afecta
retries int 10 Reintentos de descarga; solo muerde en el camino de audio (el extractor de YouTube de yt-dlp no reintenta 403/429)
sleep_subrequests float 2 Segundos entre las peticiones HTTP dentro de una extracción (watch page, llamada player, continuations). Se reenvía a yt-dlp como sleep_interval_requests (nombre interno del proyecto; el yt-dlp no tiene ninguna opción llamada sleep_subrequests)
extractor_retries int 3 Reintentos durante la extracción (solo 5xx y red)
socket_timeout float 30.0 Timeout de socket; sin él una conexión colgada bloquea el worker para siempre

Bloque sync — discovery incremental

Re-escanear un canal trackeado lee la pestaña /videos (cronológica inversa) y corta al ver overlap vídeos ya conocidos: un sync rutinario cuesta 1 página, no el canal entero.

Clave Tipo Default Qué afecta
incremental bool true Activar el modo ventana. false (o --full / "Full rescan" en la webapp) recorre todo el canal
window int 30 Entradas leídas en la primera pasada
max_window int 300 Techo: si TODA la ventana resulta nueva, se duplica hasta aquí antes de declarar el scan truncado (aviso "usa --full")
overlap int 3 Vídeos conocidos consecutivos que dan la sincronización por alcanzada

Rutas y plantillas

Clave Tipo Default Qué afecta
database_path str "data/state.db" Ruta de la BD SQLite (WAL). Relativa al CWD
output_dir str "data/markdown" Directorio de notas; el resto de datos (audio/, thumbnails/, ...) se deriva de su padre
template_path str "templates/video.md.j2" Plantilla Jinja2 de la nota. OJO: el formato del .md es un contrato bidireccional (los regex de segments.py lo re-lean)
filename_template str "{upload_date}_{slug}" Patrón del nombre de las notas. Placeholders: {upload_date} (fecha de subida; unknown-date si se desconoce), {slug} (slug del título, máx 60), {title} (título crudo), {video_id} (id estable de YouTube — útil porque título y fecha son inestables)

Ejemplos

Mínima (defaults razonables, primer contacto):

channel_url: "https://www.youtube.com/@MiCanal/videos"
languages:
  es: any

Conservadora (muchos vídeos, webapp y CLI a la vez, o historial de rate-limits):

channel_url: "https://www.youtube.com/@MiCanal/videos"
languages:
  es: any
  es-419: any
  en: any
prefer_manual: true
include_shorts: false
min_duration_sec: 30

delay:
  min_seconds: 1.5
  max_seconds: 3.5
  backoff_base: 2.0
  backoff_cap: 60.0
  throttle_threshold: 3
  min_request_interval: 2.5     # pacer global: la palanca más eficaz contra el bot-wall

sync:
  incremental: true
  window: 30
  max_window: 300
  overlap: 3

Si cambias los tiempos, vuelve a medir sobre tu canal: la constante es ~3 peticiones a youtube.com por vídeo y de ahí sale todo lo demás.