En la etapa anterior comprobamos que los subtítulos de YouTube existen y se bajan. Eso responde a «¿se puede?». Falta la pregunta que decide si el proyecto sale bien: ¿cuánto material hay realmente?
Es la pregunta que más se salta la gente. Se encuentran dos o tres fuentes prometedoras, se da por hecho que «habrá más», y se construye el pipeline entero. Cuando aparece el corpus real, ya es tarde para cambiar de estrategia.
Tras medir un solo podcast de 20.004 palabras, la conclusión fue «cinco o seis vídeos así y superamos el objetivo». Era falso, y se tardó una hora en descubrirlo. Palabras no son frases: hay que medir también la densidad, y eso exige leer una muestra.
Paso 1 — Barrido amplio, no dos búsquedas
Una búsqueda da lo que YouTube considera popular, no lo que existe. Con diez consultas salieron 30 candidatos. Con cuarenta y cuatro salieron 76 y el triple de horas. La diferencia no es el buscador: es cuántos ángulos distintos se le atacan.
Ángulos que funcionan, y que conviene combinar:
- Variantes del nombre — nombre real, apodo, apellido solo.
- Formatos — entrevista, podcast, charla, conferencia, coloquio, tertulia, ponencia, masterclass, mesa redonda.
- Temas de los que habla — su ciudad, sus rivales, sus victorias, sus aficiones.
- Programas y medios donde suele aparecer.
#!/bin/zsh
Q=(
"Perico Delgado entrevista" "Pedro Delgado podcast"
"Perico Delgado conferencia" "Perico Delgado tertulia"
"Perico Delgado Segovia" "Perico Delgado Indurain"
# ...44 consultas en total
)
for q in "${Q[@]}"; do
yt-dlp "ytsearch25:$q" --flat-playlist \
--print "%(duration)s|%(title)s|%(id)s|%(channel)s"
done--flat-playlist es la clave: pide solo los metadatos del listado, sin abrir cada vídeo. Un barrido de 1.100 resultados tarda minutos en vez de horas.
Paso 2 — Filtrar el ruido con la máquina
551 vídeos únicos salieron del barrido. La mayoría no valen, y revisarlos a mano es inviable. Tres filtros automáticos quitan casi todo:
import re
RUIDO = re.compile(
r"marcha|cicloturista|gameplay|spectrum|"
r"pro cycling manager|stage \d",
re.I,
)
candidatos = []
vistos = set()
for linea in open("barrido.txt", encoding="utf-8"):
partes = linea.rstrip("\n").split("|")
if len(partes) != 4 or not partes[0].isdigit():
continue
duracion, titulo, video_id, canal = int(partes[0]), *partes[1:]
if video_id in vistos: # 1. el mismo video sale en varias busquedas
continue
vistos.add(video_id)
if not re.search(r"perico|pedro delgado", titulo, re.I):
continue # 2. no habla de el
if duracion < 600 or RUIDO.search(titulo):
continue # 3. corto, o ruido conocido
candidatos.append((duracion, titulo, video_id, canal))
candidatos.sort(reverse=True) # los mas largos primeroQué hace cada pieza de Python nueva
| Código | Qué es | Equivalente en JS |
|---|---|---|
set() | Conjunto sin duplicados. Comprobar si algo está dentro es instantáneo | new Set() |
re.compile(...) | Expresión regular precompilada. re.I = ignorar mayúsculas | /.../i |
*partes[1:] | Desempaqueta el resto de la lista en variables sueltas | ...rest en destructuring |
continue | Salta a la siguiente vuelta del bucle | idéntico |
sort(reverse=True) | Ordena en el sitio, no devuelve copia | .sort() sí devuelve |
El filtro por nombre arrastra homónimos. En este proyecto aparecieron un médico, un académico chileno y un videojuego de Spectrum de 1989 llamado igual que el protagonista. Ningún filtro automático los distingue: hay que mirar la lista final con los ojos.
Paso 3 — Minar canales, no solo búsquedas
Este paso multiplica el inventario y casi nadie lo hace. La lógica es simple: si un canal publicó un vídeo bueno, probablemente tenga más. Un podcast que lo entrevistó una vez lo entrevista cada temporada.
Se detecta contando qué canales se repiten entre los candidatos:
import collections
cuenta = collections.Counter(canal for _, _, _, canal in candidatos)
for canal, n in cuenta.most_common():
if n > 1:
print(f"{n}x {canal}")Y luego se lista el canal entero, que es mucho más barato que buscar a ciegas:
url=$(yt-dlp --print "%(channel_url)s" --skip-download "$VIDEO_URL")
yt-dlp "${url}/videos" --flat-playlist --playlist-end 300 \
--print "%(duration)s|%(title)s|%(id)s|%(channel)s"Aquí apareció lo que ninguna búsqueda había devuelto: un canal oficial del propio Perico. Buscando por temas nunca sale; minando canales, sí.
Paso 4 — Medir de verdad, no estimar
Con la lista filtrada, se bajan los subtítulos de todos y se cuentan palabras. Es la única forma de saber qué hay.
import re, pathlib
def texto_de_vtt(ruta):
"""Convierte un .vtt en texto corrido, sin tiempos ni duplicados."""
lineas = []
for linea in ruta.read_text(encoding="utf-8").splitlines():
# fuera cabeceras y marcas de tiempo
if "-->" in linea or linea.startswith(("WEBVTT", "Kind:", "Language:")):
continue
if not linea.strip():
continue
linea = re.sub(r"<[^>]+>", "", linea).strip() # fuera etiquetas
# los subtitulos automaticos repiten la linea anterior al avanzar
if linea and (not lineas or lineas[-1] != linea):
lineas.append(linea)
return re.sub(r"\s+", " ", " ".join(lineas))
total = 0
for fichero in sorted(pathlib.Path("subs").glob("*.vtt")):
n = len(texto_de_vtt(fichero).split())
total += n
print(f"{n:>7,} {fichero.name}")
print(f"TOTAL {total:,} palabras")Ese lineas[-1] != linea importa más de lo que parece: los subtítulos automáticos repiten la línea anterior cada vez que avanzan, para dar el efecto de texto que se desliza. Sin ese filtro, el recuento sale al doble.
Paso 5 — Medir la densidad, no solo el volumen
Este es el paso que se salta todo el mundo, y el que evita construir sobre una expectativa falsa.
Se coge una muestra de unos cientos de palabras y se lee. Con 105.525 palabras recogidas, la cuenta de frases aprovechables sobre la muestra dio una por cada 250-350 palabras. Es decir: unas 350 frases, no los «miles» que sugería el volumen bruto.
Leer la muestra reveló además algo que ninguna métrica automática habría dicho:
«...tuviste que aprender francés efe a leches...» — era «a hachazos»
«...los triunfos de la unsj amstrong...» — era «Lance Armstrong»
Un fragmento que hay que reparar para entenderlo deja de ser una cita: es una reconstrucción. Si se indexa, el sistema aprende a imitar el error.
Volumen bruto × densidad = corpus real. Medir solo el volumen te da un número entre tres y diez veces optimista, y no lo descubres hasta tener el pipeline montado.
Resumen del método
| Paso | Qué responde | Coste |
|---|---|---|
| 1. Barrido amplio | ¿Qué existe? | minutos |
| 2. Filtro automático | ¿Qué es del tema? | segundos |
| 3. Minado de canales | ¿Qué no devolvió la búsqueda? | minutos |
| 4. Medición | ¿Cuánto volumen hay? | minutos |
| 5. Muestra leída | ¿Cuánto sirve? | 15 minutos, y es el paso decisivo |
Media hora larga en total, y sustituye una suposición por un número. En un proyecto donde el corpus es el producto, es la mejor media hora que vas a invertir.
Accesible no es lo mismo que rentable
El inventario responde «cuánto hay». La pregunta que viene justo detrás es «¿hace falta más?», y ahí se cuela el error más caro de todos.
Buscando fuentes aparece siempre una que tienta: enorme y, además, accesible. En este proyecto fue el archivo de RTVE, la televisión pública española. Perico lleva décadas siendo su comentarista de ciclismo, así que son años de retransmisiones con él hablando — volumen prácticamente ilimitado.
Y es accesible de verdad. yt-dlp trae extractores para RTVE — los módulos que saben hablar con cada web concreta — y funcionan:
rtve.es:alacarta
rtve.es:program
rtve.es:televisionNo hay ninguna barrera técnica. Y aun así es la peor de las cinco fuentes que se valoraron.
El motivo es la densidad. Una retransmisión de carrera es, en su mayor parte, narración técnica: «cambia el ritmo, quiere reaccionar el otro». Y el micrófono se comparte con el compañero de cabina sin ninguna marca de quién habla, así que a la poca cosecha hay todavía que restarle lo que dijo el otro.
Medido sobre un recopilatorio de retransmisiones — el mismo que ya salió en la etapa 2 con la densidad marcada como «baja»:
| Material | Frases aprovechables |
|---|---|
| Entrevista o podcast | 1 por cada ~300 palabras |
| Retransmisión | 2 o 3 en 1.503 palabras, o sea 1 por cada ~600 |
La mitad de rendimiento por palabra, y eso antes de descontar lo que dijo el compañero.
Aquí está lo que cuesta ver: una fuente con el doble de volumen y la mitad de densidad no es el doble de buena — es lo mismo, cobrado al doble. Duplicas las horas de audio que bajar, la transcripción, el texto que limpiar y el coste de clasificar, para acabar con la misma cantidad de frases. Con un factor de diez, la aritmética es idéntica y el destrozo es de diez.
«Es accesible» y «merece la pena» son dos preguntas distintas, y la primera no contesta a la segunda.
Descargar la programación completa de una televisión no es lo mismo que transcribir vídeos que alguien subió públicamente a una plataforma: es otra escala de copia. No lo descarta para uso personal, pero es una decisión que se toma antes de bajarse cincuenta horas de Tour, no una que se descubre después.
Decide midiendo lo que ya tienes, no suponiendo que necesitas más
La otra mitad de la respuesta es más incómoda, porque casi siempre significa no hacer nada.
Con unas 400.000 palabras limpias y la densidad estimada de una frase por cada 300, la proyección son unas 1.300 frases: ya dentro del objetivo. Dicho de otro modo, en el momento exacto de la tentación la fuente enorme no hacía falta. Ir a por ella antes de contar el rendimiento real de lo que ya hay en casa es la forma más segura de acabar procesando cincuenta horas de material flojo que nadie necesitaba.
Y es el tercer caso del mismo patrón en este proyecto:
- Al principio de esta etapa, estimar el corpus entero a partir de un solo podcast de 20.004 palabras.
- En la etapa 8, dar por buenas las transcripciones leyendo trozos del medio de los ficheros.
- Y ahora, dar por hecho que hace falta más material sin haber contado el que ya se tiene.
Tres veces no es mala suerte. Es extrapolar en vez de contar, y reaparece siempre que un número es caro de conseguir y fácil de estimar a ojo.
Cuando de verdad se queda corto, la siguiente fuente se elige por densidad por hora invertida, no por volumen disponible. Aquí el orden quedó así:
- Radio y podcasts fuera de YouTube. Mismo tratamiento que ya está montado, y densidad de entrevista.
- Prensa escrita con citas entrecomilladas. Poco volumen, pero el texto viene perfecto: ni un error de transcripción que reparar.
- Retransmisiones. La última, y filtrando muy fuerte.
Fíjate en que la lista va justo al revés que el volumen disponible: las retransmisiones son, de largo, lo que más material tiene.