YouTube summary
Pipeline: obtener transcripción -> leer todo -> escribir un resumen estructurado en Markdown -> renderizar PDF.
scripts/fetch_transcript.py maneja el primer paso y scripts/md_to_pdf.py el último. Tú escribes el resumen en el medio.
1. Acceso: solo lo que el usuario ya pueda ver
- Los videos públicos y no listados no requieren inicio de sesión. Intenta siempre esos primero sin cookies.
- Un video privado o solo para miembros hace que el script termine con
NEEDS_SIGNIN. Solo puedes continuar leyendo cookies de un navegador donde la cuenta del usuario que tiene acceso concedido haya iniciado sesión.- Pregunta qué navegador (y perfil, si usa más de uno) antes de pasar
--browser. Las cookies son sus credenciales. - Diles que la documentación de yt-dlp advierte que el uso automatizado de una cuenta con inicio de sesión puede resultar en limitación de velocidad o prohibición. Para sus propias subidas, la descarga desde YouTube Studio o Google Takeout es la alternativa sin riesgo, y el script acepta el archivo local resultante.
- Pregunta qué navegador (y perfil, si usa más de uno) antes de pasar
- Nunca intentes evitar configuraciones de privacidad, bloqueos regionales, DRM o muros de pago, y nunca uses la cuenta de otra persona. Si la cuenta del usuario no puede ver el video, dímelo y detente.
- "Este video es privado" incluso con
--browsergeneralmente significa que la cuenta con acceso no es la cuenta predeterminada del navegador. Sugiere--browser chrome:"Profile 2", o iniciar sesión con esa cuenta en un perfil nuevo.
2. Obtener la transcripción (desvinculado: videos largos toman tiempo)
Usa una carpeta de trabajo duradera, nunca un bloc de notas de sesión, que puede borrarse a mitad del trabajo: ~/youtube-summaries/<video-id-o-nombre-de-archivo>/.
Inicia el trabajo desvinculado para que sobreviva al final de la sesión:
OUT=~/youtube-summaries/<id>; mkdir -p "$OUT"
nohup python3 -I ~/.claude/skills/youtube-summary/scripts/fetch_transcript.py "<url-o-archivo>" \
--out "$OUT" [--browser chrome] [--lang en|auto] [--force-audio] [--audio mp3|m4a|wav] \
> "$OUT/run.log" 2>&1 &!
Luego espera con un bucle Bash en segundo plano en lugar de sondear, por ejemplo:
until grep -qE '^(DONE|FAILED|NEEDS_SIGNIN)' "$OUT/status"; do sleep 15; done; cat "$OUT/status".
Lo que hace el script:
- sondea los metadatos, luego usa subtítulos manuales, y recurre a subtítulos automáticos;
- sin subtítulos, descarga el audio y lo transcribe con mlx-whisper large-v3-turbo en Apple Silicon (openai-whisper en otros lugares). Obtiene ffmpeg de
imageio-ffmpegsi no está instalado; - elimina las alucinaciones de silencio de Whisper ("Thank you.") y las repeticiones continuas en subtítulos automáticos;
- escribe
transcript.txtcomo párrafos de 2 minutos[h:mm], másmeta.json.
Tiempo: aproximadamente 4–5 minutos de transcripción por hora de audio en un Mac con serie M y 8 GB, además del tiempo de descarga. Informa al usuario el tiempo de espera esperado, y si piden progreso, reporta el % de descarga o la última marca de tiempo en run.log.
Usa --force-audio cuando los subtítulos automáticos sean pobres (música, acentos fuertes, idioma incorrecto). Usa --lang auto para videos no en inglés.
Extracción de audio: pasa --audio mp3 (o m4a/wav) cuando el usuario quiera el audio en sí: "dame el mp3", "extrae el audio", una versión de podcast o escucha sin conexión. El archivo se guarda como <título>.<formato> en $OUT, y su ruta se registra como audio_file en meta.json. Los subtítulos aún se usan para la transcripción cuando están disponibles, por lo que solicitar audio no fuerza una transcripción lenta. Si el usuario solo quiere el audio y ningún resumen, detente después de este paso e informa el archivo.
3. Leer todo, luego resumir
Lee todo el transcript.txt; el usuario generalmente quiere cada detalle. Por encima de ~60k palabras, léelo en fragmentos ordenados y toma notas por fragmento antes de escribir.
Escribe $OUT/summary.md con tus propias palabras: un resumen, no una transcripción. Las citas cortas están bien; los pasajes extensos literales no. Estructura predeterminada (adapta las secciones al video):
# <Título del video>
| | |
|---|---|
| Video | <título> |
| Canal | <canal> |
| Enlace | <url> |
| Duración | <duración> |
| Orador(es) | <solo nombres realmente mencionados en el video> |
| Transcripción | <subtítulos manuales / subtítulos automáticos / transcripción local con Whisper> |
## 1. De un vistazo
- 5-8 viñetas: qué cubre el video y las conclusiones principales
## Línea de tiempo
| Hora | Tema |
|---|---|
| 0:00 | ... |
## 2. <Sección por capítulo/tema, en orden del video>
### <Subtema>
- cada hecho concreto, número, nombre, definición, ejemplo, paso, advertencia y recomendación
- demostraciones y tutoriales como pasos numerados; comparaciones como tablas
## Hechos clave / conclusiones
| Elemento | Valor |
## Notas sobre este resumen
> Cómo se produjo la transcripción; términos malinterpretados que corregiste; declaraciones que el orador dijo incorrectamente (con la corrección); cualquier cosa inaudible o incierta.
Por qué esta forma: la línea de tiempo permite al lector saltar al video; las tablas recopilan los hechos que la gente busca después; la sección de notas te mantiene honesto sobre los errores de transcripción. El reconocimiento de voz distorsiona los nombres de productos y la jerga, así que corrígelos según el contexto y enumera las correcciones. Verifica los hechos que el orador indica incorrectamente en lugar de repetirlos.
Mantén el cuerpo fundamentado: todo lo que esté por encima de la sección Notas debe provenir de la transcripción o meta.json. Los lectores tratan el documento como un registro de lo que dice el video, por lo que las cosas que sabes sobre el video (quién es realmente el orador, dónde se filmó, su historia) no pertenecen al cuerpo, incluso si estás seguro. Si ese contexto realmente ayuda, ponlo en Notas y etiquétalo como "fuera del video". Nunca asignes nombres o pronombres que el video no proporcione. Si la descripción del video no está relacionada con el contenido (las descripciones reutilizadas o spam son comunes), ignórala y dímelo en Notas.
Dimensiona el documento según el video. Usa <!-- pagebreak --> solo para iniciar una nueva parte importante de un documento largo (por ejemplo, cada capítulo de una transmisión de varias horas), nunca después de la tabla de portada. Un clip de 2 minutos debe caber en una o dos páginas.
4. Renderizar y verificar el PDF
uv run ~/.claude/skills/youtube-summary/scripts/md_to_pdf.py "$OUT/summary.md" "$OUT/<Título>.pdf"
Renderiza la página 1 y una página densa a PNG, y míralas antes de informar:
uvx --with pypdfium2 --with pillow python -c "...".
Luego dale al usuario:
- la ruta absoluta del PDF y el número de páginas;
- un resumen de 3-5 líneas;
- cualquier advertencia: transcripción generada automáticamente, secciones que fueron inaudibles.
El archivo de audio puede ser grande. Menciónalo y deja que el usuario decida si eliminarlo.
Solución de problemas
Inicia sesión para confirmar que no eres un bot/ HTTP 403 en un video público: espera y vuelve a intentarlo. Si persiste, es un problema de IP o límite de velocidad. No hagas un bucle.- Advertencias de yt-dlp sobre tiempo de ejecución JS: el script pasa
--js-runtimes nodecuando Deno está ausente. Se necesita Node 22+. - Sin palabras en la transcripción, o una transcripción llena de basura: verifica el idioma (
--lang auto), o vuelve a ejecutar con--force-audio.