ESPACIO PUBLICITARIO DISPONIBLE · HABLEMOS

Transmisión de voz en streaming y configuración de parámetros de voz con la API de Listnr

365Finds Editorial
11.430 artículos Wiki recopilados

Usa 365 Wiki con tu IA

Copia el prompt de abajo, pégalo en la IA que ya usas y haz tu pregunta.

Descargar el Skill completo

Pruébalo primero con el prompt. Si usas 365 Wiki a menudo, instala el Skill completo de 365Wiki y no tendrás que volver a pegarlo. Si no tienes una IA habitual, también sirven las versiones web de Gemini o Microsoft Copilot.

La integración de síntesis de voz en tiempo real (Text-to-Speech o TTS) en aplicaciones web modernas exige un equilibrio riguroso entre la latencia de respuesta, la naturalidad de la locución y la protección de las credenciales de la API. Listnr ofrece una arquitectura de dos niveles: una interfaz REST V1 multiproveedor que agrupa voces de Microsoft Azure, Google Cloud, AWS Polly e IBM Watson, y un motor de streaming V2 de baja latencia diseñado específicamente para voces Ultra Premium y clonadas.

Para transmitir voz sintetizada en clientes web sin exponer credenciales sensibles, el patrón de diseño recomendado consiste en implementar un proxy en el backend que reciba las solicitudes del navegador, agregue el token de autorización, invoque el endpoint /stream-voice de Listnr y canalice (pipe) los fragmentos de audio binario directamente hacia la aplicación web.

sequenceDiagram
    autonumber
    actor User as Navegador Web (Cliente)
    participant Server as Backend de la Aplicación (Proxy)
    participant Listnr as API de Streaming Listnr V2
    
    User->>Server: POST /api/tts (texto, voiceId, ajustes)
    Note over Server: Inserta x-listnr-token de forma segura
    Server->>Listnr: POST /api/v2/stream-voice
    Listnr-->>Server: Flujo binario fragmentado (WAV / MP3)
    Server-->>User: Flujo canalizado (Transfer-Encoding: chunked)
    Note over User: Web Audio API / HTML5 Audio inicia reproducción inmediata

1. Fundamentos de autenticación y arquitectura del sistema

Las aplicaciones web en el frontend nunca deben invocar los endpoints de Listnr directamente utilizando claves de producción. Listnr valida las peticiones mediante un encabezado propietario (x-listnr-token), el cual se vincula directamente a la cuota de palabras contratada y al plan de facturación de la cuenta. Exponer esta clave en el paquete de scripts del cliente facilita la filtración del token y el agotamiento no autorizado de créditos.

Protección de credenciales y arquitectura de proxy

La práctica recomendada en entornos de producción consiste en interponer una capa intermedia en el servidor (como Next.js API Routes, Express, Fastify o FastAPI).

Componente APIHost / EndpointPropósito principalRequisitos de seguridad
Streaming V2https://cloning.listnr.tech/api/v2/stream-voiceTransmisión binaria de baja latencia para voces Ultra Premium y clonesExclusivo en servidor; requiere x-listnr-token
Exploración de voces V2https://cloning.listnr.tech/api/v2/available-voicesLista de identificadores de voz, perfiles predefinidos y clones de cuentaAlmacenar en caché en backend; consultar vía proxy
REST V1 multiproveedorhttps://bff.listnr.tech/api/tts/v1/convert-textConversión por lotes para voces de Azure, Google, AWS e IBMUso en servidor; admite etiquetas raíz SSML completas

2. Descubrimiento de voces: obtención de identificadores

Antes de generar el audio, la aplicación debe contar con un identificador de modelo válido (voice_id). Este listado puede consultarse durante el inicio del servidor o almacenarse en una memoria caché distribuida como Redis.

# Consultar voces predefinidas y clonadas disponibles en la cuenta
curl -X GET "https://cloning.listnr.tech/api/v2/available-voices" \
  -H "x-listnr-token: TU_API_KEY_DE_LISTNR" \
  -H "Accept: application/json"

La respuesta entrega un arreglo de objetos de voz con identificadores alfanuméricos únicos (por ejemplo, 21m00Tcm4TlvDq8ikWAM). El frontend remite este identificador al backend para direccionar la síntesis al modelo acústico deseado.


3. Síntesis en streaming y configuración de parámetros vocales

El endpoint de streaming V2 de Listnr procesa un cuerpo JSON con el texto de entrada, el identificador de voz y un objeto settings encargado de modular el comportamiento acústico.

{
  "voice_id": "21m00Tcm4TlvDq8ikWAM",
  "text": "Alerta del sistema: La sincronización de réplicas presentó retraso.<break time=\"0.4s\"/><break strength=\"strong\"/>Iniciando protocolo de conmutación.",
  "settings": {
    "stability": 0.71,
    "similarity_boost": 0.50,
    "style": 0.05,
    "use_speaker_boost": false
  }
}

Guía de ajuste de parámetros

Ajustar de manera deliberada estos parámetros evita artefactos sonoros y variaciones indeseadas:

Pausas y modulación de ritmo con SSML

En el flujo de streaming V2, no es necesario estructurar un documento formal con <speak>. Los desarrolladores pueden incorporar etiquetas de pausa directamente dentro de la cadena de texto:


4. Implementación web de extremo a extremo

El siguiente código describe una solución de nivel productivo compuesta por un proxy de streaming en Node.js/Express y un cliente web que consume y reproduce el flujo de datos.

Proxy de streaming en el backend (server.js)

import express from 'express';
import fetch from 'node-fetch';

const app = express();
app.use(express.json());

const LISTNR_API_KEY = process.env.LISTNR_API_KEY;
const STREAM_URL = 'https://cloning.listnr.tech/api/v2/stream-voice';

app.post('/api/tts/stream', async (req, res) => {
  try {
    const { text, voiceId, settings } = req.body;

    if (!text || !voiceId) {
      return res.status(400).json({ error: 'Falta el parámetro text o voiceId.' });
    }

    const payload = {
      voice_id: voiceId,
      text: text,
      settings: {
        stability: settings?.stability ?? 0.71,
        similarity_boost: settings?.similarity_boost ?? 0.50,
        style: settings?.style ?? 0.0,
        use_speaker_boost: settings?.use_speaker_boost ?? false
      }
    };

    const upstreamResponse = await fetch(STREAM_URL, {
      method: 'POST',
      headers: {
        'x-listnr-token': LISTNR_API_KEY,
        'Content-Type': 'application/json',
        'Accept': '*/*'
      },
      body: JSON.stringify(payload)
    });

    if (!upstreamResponse.ok) {
      const errorText = await upstreamResponse.text();
      return res.status(upstreamResponse.status).json({
        error: `Error en la API de Listnr: ${upstreamResponse.statusText}`,
        details: errorText
      });
    }

    // Configurar encabezados para flujo fragmentado
    res.setHeader('Content-Type', 'audio/wav');
    res.setHeader('Transfer-Encoding', 'chunked');

    // Canalizar la respuesta binaria directamente al cliente
    upstreamResponse.body.pipe(res);
  } catch (err) {
    console.error('Fallo en el streaming de TTS:', err);
    res.status(500).json({ error: 'Error interno en el servidor proxy.' });
  }
});

app.listen(3000, () => console.log('Proxy de audio ejecutándose en el puerto 3000'));

Reproducción en el cliente web (client.js)

/**
 * Solicita el flujo de audio al backend e inicia la reproducción
 */
async function streamAndPlayAudio(text, voiceId) {
  const response = await fetch('/api/tts/stream', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      text: text,
      voiceId: voiceId,
      settings: {
        stability: 0.65,
        similarity_boost: 0.60,
        style: 0.0
      }
    })
  });

  if (!response.ok) {
    throw new Error(`Error en la descarga de audio: ${response.status}`);
  }

  // Convertir el flujo binario a Blob y reproducir mediante HTML5 Audio
  const audioBlob = await response.blob();
  const audioUrl = URL.createObjectURL(audioBlob);
  const audio = new Audio(audioUrl);
  
  audio.onended = () => URL.revokeObjectURL(audioUrl);
  await audio.play();
}

5. Criterios de arquitectura para entornos en producción

Antes de desplegar esta solución a gran escala, conviene sopesar las siguientes consideraciones técnicas:

  1. Selección entre REST V1 y Streaming V2: Utiliza V1 cuando tu sistema dependa de las voces neuronales consolidadas de Azure o Google, o requiera marcas de tiempo a nivel de palabra para sincronizar subtítulos. Emplea el streaming V2 cuando la prioridad radique en la inmediatez interactiva y la calidad acústica de voces clonadas.
  2. Control de consumo y limitación de peticiones (Debounce): Dado que cada llamada descuenta créditos de palabras, en interfaces interactivas de chat es fundamental aplicar una técnica de debounce al texto y cancelar peticiones en curso con AbortController si el usuario genera un nuevo mensaje.
  3. Caché perimetral para locuciones estáticas: Las advertencias fijas del sistema y las instrucciones operativas estándar deben sintetizarse una única vez y almacenarse en un bucket de objetos (como Amazon S3) respaldado por una CDN, reservando el streaming en vivo para contenidos generados dinámicamente.

Referencias