ESPACE PUBLICITAIRE DISPONIBLE · PARLONS-EN

Diffusion audio en continu et configuration des paramètres vocaux avec l'API Listnr TTS

365Finds Editorial
11 430 articles Wiki répertoriés

Utilisez 365 Wiki avec votre IA

Copiez le prompt ci-dessous, collez-le dans l’IA que vous utilisez déjà, puis posez directement votre question.

Télécharger le Skill complet

Commencez par essayer le prompt. Si vous utilisez souvent 365 Wiki, installez le Skill 365Wiki complet pour ne plus avoir à le coller. Sans IA habituelle, les versions web de Gemini ou Microsoft Copilot conviennent aussi.

L'intégration d'un moteur de synthèse vocale (Text-to-Speech ou TTS) en temps réel dans les applications web modernes exige un compromis rigoureux entre faible latence de restitution, expressivité acoustique et sécurité des identifiants d'API. Listnr répond à cette exigence via une architecture double : d'un côté, une interface REST V1 multi-fournisseurs regroupant les voix de Microsoft Azure, Google Cloud, AWS Polly et IBM Watson ; de l'autre, une interface de streaming V2 à très faible latence spécialement conçue pour les voix Ultra Premium et les voix clonées.

Pour diffuser de la voix synthétisée dans un navigateur sans compromettre les clés secrètes, l'architecture recommandée consiste à déployer un proxy backend. Ce service relaie les requêtes du client, injecte l'en-tête d'authentification requis, appelle le point de terminaison /stream-voice de Listnr et achemine (pipe) directement les segments binaires d'audio vers le navigateur.

sequenceDiagram
    autonumber
    actor User as Navigateur Web (Client)
    participant Server as Backend de l'Application (Proxy)
    participant Listnr as API de Streaming Listnr V2
    
    User->>Server: POST /api/tts (texte, voiceId, réglages)
    Note over Server: Injection sécurisée de x-listnr-token
    Server->>Listnr: POST /api/v2/stream-voice
    Listnr-->>Server: Flux binaire fractionné (WAV / MP3)
    Server-->>User: Acheminement du flux (Transfer-Encoding: chunked)
    Note over User: Lecture immédiate via HTML5 / Web Audio API

1. Principes d'authentification et architecture sécurisée

Les interfaces frontend ne doivent sous aucun prétexte invoquer les points de terminaison de Listnr avec une clé d'API de production. Listnr valide les requêtes via un en-tête propriétaire (x-listnr-token), directement adossé au solde de mots et au forfait de facturation du compte. Exposer cette clé côté client présente un risque immédiat d'épuisement non autorisé des quotas.

Isolation des clés et proxy backend

Le schéma d'intégration standard place une couche relais côté serveur (telle que des routes d'API Next.js, Express, Fastify ou FastAPI) entre le navigateur et les serveurs de Listnr.

Composant APIHôte / Point de terminaisonRôle principalExigences d'accès
Streaming V2https://cloning.listnr.tech/api/v2/stream-voiceFlux binaire à très faible latence pour voix Ultra Premium et clonesBackend uniquement ; en-tête x-listnr-token
Catalogue de voix V2https://cloning.listnr.tech/api/v2/available-voicesÉnumération des identifiants, profils standards et clones du compteMise en cache backend ; consultation via proxy
REST V1 multi-fournisseurshttps://bff.listnr.tech/api/tts/v1/convert-textGénération de fichiers par lots pour les voix Azure, Google, AWS, IBMBackend uniquement ; accepte les balises racine SSML

2. Découverte des voix : récupération des identifiants de modèles

Avant d'exécuter une synthèse, l'application doit connaître l'identifiant unique du modèle vocal (voice_id). Cet inventaire peut être extrait lors de l'initialisation du serveur backend et conservé dans un cache mémoire tel que Redis.

# Récupérer les voix prédéfinies et clonées disponibles pour le compte
curl -X GET "https://cloning.listnr.tech/api/v2/available-voices" \
  -H "x-listnr-token: VOTRE_CLE_API_LISTNR" \
  -H "Accept: application/json"

La réponse renvoie un tableau d'objets contenant des identifiants alphanumériques uniques (par exemple 21m00Tcm4TlvDq8ikWAM). Le client web transmet cet identifiant au backend pour cibler le modèle acoustique approprié.


3. Synthèse en streaming et paramétrage vocal sur mesure

Le point de terminaison de streaming V2 accepte un corps de requête au format JSON comprenant le texte source, l'identifiant de la voix et un objet settings destiné à affiner le timbre.

{
  "voice_id": "21m00Tcm4TlvDq8ikWAM",
  "text": "Alerte système : Délai détecté dans la réplication de base de données.<break time=\"0.4s\"/><break strength=\"strong\"/>Déclenchement du protocole de basculement.",
  "settings": {
    "stability": 0.71,
    "similarity_boost": 0.50,
    "style": 0.05,
    "use_speaker_boost": false
  }
}

Guide d'étalonnage des paramètres vocaux

Une configuration méthodique des paramètres permet de concilier expressivité et stabilité sonore :

Pauses et modulation du rythme avec SSML

Sur le point de terminaison V2 /stream-voice, il n'est pas nécessaire d'encadrer le contenu avec <speak>. Les développeurs peuvent inclure directement des balises de pause dans le texte :


4. Implémentation web de bout en bout

L'exemple ci-dessous illustre une solution complète prête pour la production, comprenant un proxy de streaming en Node.js/Express et un script client assurant la réception et la lecture instantanée dans le navigateur.

Proxy de streaming côté serveur (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: 'Paramètre text ou voiceId manquant.' });
    }

    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: `Erreur API Listnr : ${upstreamResponse.statusText}`,
        details: errorText
      });
    }

    // Définition des en-têtes pour un transfert fragmenté en continu
    res.setHeader('Content-Type', 'audio/wav');
    res.setHeader('Transfer-Encoding', 'chunked');

    // Acheminement direct du flux reçu vers la réponse du client
    upstreamResponse.body.pipe(res);
  } catch (err) {
    console.error('Erreur de streaming TTS :', err);
    res.status(500).json({ error: 'Erreur interne du proxy relais.' });
  }
});

app.listen(3000, () => console.log('Proxy audio démarré sur le port 3000'));

Lecture instantanée côté client (client.js)

/**
 * Récupère le flux audio auprès du backend et lance la lecture sans délai
 */
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(`Échec de la récupération audio : ${response.status}`);
  }

  // Conversion du flux binaire en Blob et lecture immédiate avec 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. Arbitrages techniques et mise en production

Lors du déploiement en environnement de production, plusieurs choix d'architecture s'imposent :

  1. Sélection entre REST V1 et Streaming V2 : Privilégiez V1 lorsque votre application exploite des voix cloud traditionnelles (Azure, Google) ou nécessite un horodatage précis mot à mot (Word Timestamps) pour synchroniser un sous-titrage. Adoptez V2 lorsque la priorité absolue réside dans la réactivité instantanée et le réalisme vocal.
  2. Gestion des quotas et limitation des requêtes (Debounce) : Chaque caractère synthétisé déduit des crédits du forfait. Dans les interfaces de saisie en direct, temporisez les frappes utilisateur (debounce) et interrompez les requêtes obsolètes via AbortController dès qu'un nouveau texte est soumis.
  3. Mise en cache des messages statiques : Les invites d'accueil récurrentes et les alertes d'erreur figées doivent être synthétisées une seule fois, puis stockées dans un service de stockage objet (tel qu'Amazon S3) relayé par un CDN. Réservez l'appel direct aux flux en continu aux seules réponses dynamiques.

Références