Streaming y caché con Supabase
Streaming y caché con Supabase
Genera y transmite voz mediante las Edge Functions de Supabase. Almacena la voz en Supabase Storage y guarda las respuestas en caché mediante la CDN integrada.
Guía práctica · Da por hecho que has completado la guía de inicio rápido de ElevenAPI y que tienes una cuenta de Supabase.
Introducción
En esta guía aprenderás a crear una API perimetral para generar, transmitir, almacenar y guardar en caché voz mediante Supabase Edge Functions, Supabase Storage y ElevenLabs.
Requisitos
- Una cuenta de ElevenLabs con una clave de API.
- Una cuenta de Supabase (puedes registrarte gratis a través de database.new).
- La CLI de Supabase instalada en tu equipo.
- El runtime de Deno instalado en tu equipo y, opcionalmente, configurado en tu IDE favorito.
Configuración
Crea un proyecto de Supabase localmente
Después de instalar la CLI de Supabase, ejecuta el siguiente comando para crear un proyecto de Supabase localmente:
Configura el bucket de almacenamiento
Puedes configurar la CLI de Supabase para generar automáticamente un bucket de almacenamiento añadiendo esta configuración al archivo config.toml:
Al ejecutar supabase start, se creará un nuevo bucket de almacenamiento en tu proyecto local de Supabase. Si quieres enviar esto a tu proyecto de Supabase alojado, puedes ejecutar supabase seed buckets --linked.
Configura tareas en segundo plano para Supabase Edge Functions
Para usar tareas en segundo plano en Supabase Edge Functions durante el desarrollo local, debes añadir la siguiente configuración al archivo config.toml:
Al ejecutar con la política per_worker, Function no se recargará automáticamente al editarla. Tendrás que reiniciarla manualmente ejecutando supabase functions serve.
Crea una Supabase Edge Function para generar voz
Crea una nueva Edge Function ejecutando el siguiente comando:
Si utilizas VS Code o Cursor, selecciona y cuando la CLI te pregunte «Generate VS Code settings for Deno? [y/N]».
Configura las variables de entorno
En el directorio supabase/functions, crea un archivo .env nuevo y añade las siguientes variables:
Dependencias
El proyecto utiliza un par de dependencias:
- La biblioteca @supabase/supabase-js para interactuar con la base de datos de Supabase.
- El SDK de JavaScript de ElevenLabs para interactuar con la API de Texto a Voz.
- El proyecto de código abierto object-hash para generar un hash a partir de los parámetros de la solicitud.
Como Supabase Edge Function usa el runtime de Deno, no necesitas instalar las dependencias: puedes importarlas mediante el prefijo npm:.
Programa la Supabase Edge Function
En el archivo supabase/functions/text-to-speech/index.ts que acabas de crear, añade el siguiente código:
Análisis detallado del código
Hay un par de aspectos del código que merece la pena destacar. Vamos a verlo paso a paso.
Gestiona la solicitud entrante
Para gestionar la solicitud entrante, usa el controlador Deno.serve. En la demo no validamos el origen de la solicitud, pero puedes, por ejemplo, validarlo o añadir un token de acceso de usuario y validarlo con Supabase Auth.
A partir de la solicitud entrante, la función extrae los parámetros text y voiceId. El parámetro voiceId es opcional y, de forma predeterminada, usa el ID de ElevenLabs de la voz «Allison».
Mediante la biblioteca object-hash, la función genera un hash a partir de los parámetros de la solicitud. Este hash se usa para comprobar si existen archivos de audio en Supabase Storage.
Comprueba si existe un archivo de audio en Supabase Storage
Supabase Storage incluye una CDN inteligente integrada que te permite guardar en caché y servir fácilmente tus archivos.
Aquí, la función comprueba si existe un archivo de audio en Supabase Storage. Si el archivo existe, la función lo devuelve desde Supabase Storage.
Genera voz como flujo y divídelo en dos ramas
Mediante las capacidades de transmisión de la API de ElevenLabs, la función genera un flujo. La ventaja es que, incluso con textos más largos, puedes empezar a transmitir el audio a tu usuario de inmediato y subir el flujo a Supabase Storage en segundo plano.
Esto ofrece la mejor experiencia posible a usuarios y hace que incluso los bloques de texto grandes parezcan increíblemente rápidos. La magia ocurre en la línea 17, donde el método stream.tee() divide el flujo legible en dos ramas: una para el navegador y otra para Supabase Storage.
Sube el flujo de audio a Supabase Storage en segundo plano
El método EdgeRuntime.waitUntil de la línea 20 del paso anterior se usa para subir el flujo de audio a Supabase Storage en segundo plano mediante la función uploadAudioToStorage. Esto permite que la función devuelva la respuesta en transmisión al navegador inmediatamente mientras el audio se sube a Supabase Storage.
Una vez creado el objeto de almacenamiento, la próxima vez que tus usuarios hagan una solicitud con los mismos parámetros, la función devolverá el archivo de audio desde la CDN de Supabase Storage.
Ejecuta localmente
Para ejecutar la función localmente, usa los siguientes comandos:
Cuando el stack local de Supabase esté en funcionamiento, ejecuta el siguiente comando para iniciar la función y ver los registros:
Pruébalo
Ve a http://127.0.0.1:54321/functions/v1/text-to-speech?text=hello%20world para escuchar la función en acción.
Después, ve a http://127.0.0.1:54323/project/default/storage/buckets/audio para ver el archivo de audio en tu bucket local de Supabase Storage.
Despliega en Supabase
Si aún no lo has hecho, crea una cuenta nueva de Supabase en database.new y vincula el proyecto local a tu cuenta de Supabase:
Cuando termines, ejecuta el siguiente comando para desplegar la función:
Configura los secretos de la función
Ahora que ya tienes todos los secretos configurados localmente, puedes ejecutar el siguiente comando para configurarlos en tu proyecto de Supabase:
Prueba la función
La función está diseñada para poder usarse directamente como fuente de un elemento <audio>.