Condensando multimedia para aprender idiomas con shuku

He creado shuku para condensar películas y series conservando solo los diálogos:

¿Por qué?

Cuanto más tiempo pasas inmerso en un idioma, más rápido lo adquieres.

Escucho podcasts en japonés mientras hago ejercicio o salgo a caminar. Como principiante, la comprensión es difícil. Sin contexto, solo puedo entender palabras individuales y frases cortas.

Una forma de aumentar masivamente el contexto es repetir contenido. Escuchar la pista de audio de una película que has visto antes te permite entender más que la primera vez. ¡Sabes lo que está sucediendo y cómo terminará todo!

La idea es ver una película o un episodio de una serie, y luego escuchar la versión condensada para aumentar la comprensión.

Como se ve arriba,algunas películas tienen más silencio que otras. Si alguien quiere usar Blade Runner 2049 para aprender inglés, en lugar de escuchar las 2 horas y 43 minutos completas, puede usar shuku para obtener la versión solo con diálogos en 55 minutos. ¡Mucho más eficiente!

¿Cómo?

Los archivos de subtítulos contienen toda la información que necesitamos: todas las frases de la película con su tiempo de inicio y fin. Un fragmento de Blade Runner 2049:

78
00:14:46,094 --> 00:14:49,184
Do you feel that there's a part of you
that's missing? Interlinked.

79
00:14:49,348 --> 00:14:51,768
-Within cells interlinked.
-Within cells interlinked.

shuku usa estos tiempos para condensar el contenido. Un resumen del proceso:

  1. Se ejecuta shuku con un archivo de vídeo como Blade.Runner.2049.2017.2160p.UHD.BluRay.TrueHD.7.1.HDR.x265.mkv
  2. Si está habilitado, busca subtítulos coincidentes (si no, usa los internos)
  3. Filtra los subtítulos no deseados (ver más abajo)
  4. Crea una lista de segmentos de voz (tiempos de inicio/fin de los subtítulos)
  5. Extrae los segmentos a un directorio temporal
  6. Une los segmentos en un archivo de audio con metadatos y un nombre limpio: Blade Runner 2049 (2017) (condensed).mp3

¿Cómo se ve?

Aquí tienes un clip de Blade Runner 2049. El audio es el de la versión condensada:

INFO

Por defecto, shuku agrega medio segundo alrededor de cada línea para evitar cortes abruptos.

Como puedes ver, los fragmentos de diálogo son casi idénticos, excepto que hay menos silencio en la versión condensada. La principal diferencia es que omitimos la pelea y el viaje.

Origen de la idea

No he inventado yo la idea de «multimedia condensada»; existen al menos dos programas que pueden hacer esto: impd (para GNU+Linux) y condenser (para Windows).

Creé shuku porque ni impd ni condenser funcionaban en macOS. Mi primer enfoque fue crear un fork de condenser para reemplazar las partes específicas de Windows. Rápidamente me di cuenta de que quería implementar más cambios.

Así que me propuse crear el mejor condensador, con soporte multiplataforma, 100% de cobertura de código y amplia personalización.

El repositorio de shuku incluye una tabla comparando las tres herramientas.

Desafíos

Fuzzy matching

Dado un archivo de video Blade Runner 2049.mkv, shuku puede emparejarlo con su archivo de subtítulos Blade Runner 2049 (1080p).srt, incluso si no los nombres no coinciden al 100%.

Para lograrlo, shuku limpia tanto el nombre del archivo de entrada como todos los subtítulos potenciales. Por ejemplo:

  • Old_Movie_1950_Remastered_2023.mp4 → old movie remastered 1950 2023
  • Movie.Without.Year.1080p.BluRay.x264-GROUP.mkv → movie without year bluray
  • TV.Show.S01E01.2021.720p.WEB-DL.x264.srt → tv show s01e01 web-dl 2021

El nombre limpio del video (input) se compara con todos los nombres limpios de los archivos de subtítulos.

Para encontrar la coincidencia más cercana, mi primera idea fue usar la distancia de Hamming. Funcionaba, pero era demasiado sensible a pequeños cambios (como el orden de las palabras).

Probé múltiples enfoques y encontré la mejor precisión con SequenceMatcher de Python. Esta función se basa en el algoritmo de Ratcliff y Obershelp llamado Gestalt pattern matching.

Con la función de limpieza, el comparador de secuencias y un umbral de match ajustable, el fuzzy matching no falla.

Una línea de subtítulos podría ser [sonido de pasos]. No necesitamos incluirla en el audio condensado.

Agregué una opción de configuración que por defecto omite los subtítulos encerrados en corchetes o notas musicales (♪ o ♬). Esto último es útil para descartas los openings y endings de series.

Seguimiento del audio

shuku puede generar archivos LRC que coinciden con el audio condensado. Estos son archivos con texto sincronizado usados para letras de canciones.

Al agregar el audio y los subtítulos condensados a una app diseñada para seguir letras de canciones, como Just Player (iOS), puedo consultar los subtítulos mientras escucho:

Ahora puedo consultar la escritura de palabras que suenan familiares pero no acabo de entender; ¡súper útil para los kanji!

Detalles técnicos

Mi enfoque fue hacer shuku mantenible, fácil de instalar, fácil de usar y fácil de contribuir.

Python puede facilitar las contribuciones y me permite aprovechar pysubs2, una fantástica biblioteca para trabajar con subtítulos.

FFmpeg es la única dependencia de shuku. A través del binding python-ffmpeg, FFmpeg maneja todo el procesamiento de medios: extracción y unión de segmentos, conversión de audio…

Me centré en crear código limpio y una buena experiencia de usuario:

  • Los type hints en todo el código detectan problemas potenciales temprano.
  • Configuración fácil con TOML. Aquí está mi configuración.
  • Logging con niveles personalizados. Ayuda a los usuarios (¡y a mí!) a entender qué está pasando.
  • 100% de cobertura de código para fiabilidad y mantenibilidad.
  • CI/CD automatizados y publicación de (binarios + PyPI) para todas las plataformas con atestaciones.

Así es como se usa shuku:


Si estás aprendiendo un idioma por inmersión, seguro que encontrarás shuku útil. Echa un vistazo al repositorio de GitHub para empezar〜