Post

Semana 1: toma de contacto

Refactorizo audio_out para transmitir el audio en tiempo real con WebRTC y dejo el WebSocket solo para la señalización.

Semana 1: toma de contacto

Resumen de la semana

Partiendo del proyecto “audio_out” de la semana 2, en el que el servidor enviaba un MP3 completo por WebSocket y el navegador lo reproducía, esta semana lo he refactorizado para que el audio llegue como un flujo en tiempo real por WebRTC. El WebSocket se queda únicamente para la señalización inicial (SDP). Además, a mitad de semana decidí cambiar la arquitectura entera de este blog, lo explico con más detalle abajo.

Objetivos

  • Sustituir el envío del MP3 completo por un flujo de audio en tiempo real con WebRTC.
  • Añadir una capa previa con Piper que convierta texto en audio y lo mande al navegador.
  • Extra: reorganizar el blog (aún en local) y transformarlo de HTML a Jekyll.

Trabajo realizado

Punto de partida: audio_out (semana 2)

Tras la semana anterior, tenía un proyecto en el que un servidor Python leía un MP3 local y lo enviaba entero por WebSocket. El navegador lo recibía y lo reproducía con la etiqueta HTML “

Migración a WebRTC

La idea principal de esta semana era transformar el sistema de envío para enviar la información por WebRTC. Antes de intercambiar audio por WebRTC, las dos partes tienen que hacer una “negociación” sobre qué van a enviarse y cómo. Ese paso se llama señalización, y WebRTC no impone cómo hacerlo: solo pide que cada lado pueda pasar al otro un texto (SDP) que describa su sesión. Aproveché el WebSocket que ya tenía montado para llevar ese texto.

Cambios principales:

  • Un único servidor “aiohttp” que sirve la página (“GET /”) y gestiona la señalización (“GET /ws”), todo en el mismo bucle async.
  • “aiortc” en el servidor: “MediaPlayer” decodifica el MP3, lo trocea en frames y lo ritma a tiempo real.
  • Cliente con “RTCPeerConnection”: pide una pista de audio de solo recepción (recvonly) y la conecta al reproductor cuando llega.
  • Dependencias: “websockets” deja de ser necesaria, porque “aiohttp” aporta el soporte de WebSocket. Ahora se usan “av”, “aiohttp” y “aiortc”.

La parte central del servidor es esta función, que crea la conexión, le añade el audio y completa el intercambio SDP:

RELLENAR: captura de la página con el audio reproduciéndose

Cambio de rumbo en la arquitectura

Inicialmente planteé usar ambas tecnologías: WebRTC para el audio en tiempo real y WebSocket para señalización y control. En la última reunión de la semana, compañeros de JdeRobot me indicaron que había un problema con mi planteamiento:

  • El audio (no solo la señalización) debía viajar por WebSocket.
  • WebRTC en el navegador debía usarse solo para captar y reproducir el audio localmente, no como transporte entre navegador y servidor.

De forma que el primer reto para la siguiente semana sería decidir qué partes de esta arquitectura se podrían dejar intactas, cuáles se podrían reutilizar y cuáles deberían ser eliminadas.

Cambio de blog: HTML a Jekyll

A mediados de semana, decidí que el blog que estaba preparando no quedaba como me gstaría, así que decidí probar una alternativa a HTML: Jekyll. Otros estudiantes que han pasado por JdeRobot habían utilizado esta tecnología, incluido mi compañero de prácticas Anass, que me respondió a varias preguntas y me ayudó enormemente a entender el proceso de contrucción del blog.

Próximos pasos

  • Enviar el audio de forma continua por WebSocket en fragmentos pequeños, según la nueva arquitectura.
  • Añadir la capa con Piper para convertir texto en audio y mandarlo al navegador.
  • RELLENAR: decidir si se parte de la base de “audio_out” o se empieza de cero.

Recursos

This post is licensed under CC BY 4.0 by the author.