> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Diarisation des locuteurs

> **Note**
>
> **Guide pratique** · Suppose que vous avez suivi le guide sur le streaming
> [côté client](/docs/fr/eleven-api/guides/how-to/speech-to-text/realtime/client-side-streaming) ou le streaming
> [côté serveur](/docs/fr/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming).

## Vue d’ensemble

La diarisation des locuteurs attribue des identifiants de locuteur aux mots afin de distinguer qui a dit quoi. Lorsque la diarisation est activée, les transcriptions partielles incluent des étiquettes de locuteur provisoires, et chaque transcription validée est suivie d’un événement `diarized_transcript` distinct. Les étiquettes de locuteur peuvent changer à mesure que davantage d’audio arrive.

## Activer la diarisation

Définissez le paramètre de requête booléen `diarize=true` lors de l’ouverture d’une connexion WebSocket avec `model_id=scribe_v3_live`. La diarisation est désactivée (`false`) par défaut.

Les exemples côté serveur suivants ouvrent une connexion et reçoivent des événements. Installez `websockets` pour Python, ou `ws` et la dépendance de développement `@types/ws` pour TypeScript. Définissez `ELEVENLABS_API_KEY` dans l’environnement de votre serveur ; les exemples l’envoient dans l’en-tête `xi-api-key`. Conservez cette clé sur le serveur, et non dans le code du navigateur.

Ces exemples n’envoient pas d’audio. Intégrez-les à votre producteur audio à partir du [guide de streaming côté serveur](/docs/fr/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming) : envoyez des messages `input_audio_chunk` sur la même connexion tout en recevant les événements. Les exemples sélectionnent `pcm_16000`, utilisez donc un format audio correspondant. En Python, exécutez la tâche d’envoi audio simultanément avec la boucle de réception ; en TypeScript, envoyez l’audio après l’ouverture de la connexion.

```python
import asyncio
import json
import os

from websockets.asyncio.client import connect


async def main():
    url = (
        "wss://api.elevenlabs.io/v1/speech-to-text/realtime"
        "?model_id=scribe_v3_live&audio_format=pcm_16000&diarize=true"
    )
    headers = {"xi-api-key": os.environ["ELEVENLABS_API_KEY"]}

    async with connect(url, additional_headers=headers) as websocket:
        async for message in websocket:
            event = json.loads(message)
            print(event)


if __name__ == "__main__":
    asyncio.run(main())
```

```typescript
import WebSocket from "ws";

const apiKey = process.env.ELEVENLABS_API_KEY;
if (!apiKey) {
  throw new Error("Set ELEVENLABS_API_KEY in your server environment.");
}

const websocket = new WebSocket(
  "wss://api.elevenlabs.io/v1/speech-to-text/realtime" +
    "?model_id=scribe_v3_live&audio_format=pcm_16000&diarize=true",
  { headers: { "xi-api-key": apiKey } }
);

websocket.on("message", (message) => {
  const event = JSON.parse(message.toString());
  console.log(event);
});

websocket.on("error", (error) => {
  console.error(error);
});
```

## Gérer les événements

### Transcriptions partielles

Lorsque la diarisation est activée, chaque `partial_transcript` inclut des `words` provisoires avec la même structure de mot que la transcription par lots. Le `speaker_id` de chaque mot est `speaker_0`, `speaker_1`, etc. une fois le locuteur identifié, ou `null` tant qu’il n’est pas résolu.

Considérez ces mots comme provisoires : les identifiants de locuteur et les horodatages peuvent changer avec l’arrivée de davantage d’audio. Les mots qui n’ont pas encore été alignés ne disposent pas d’horodatages (`start` et `end` sont `null` ou absents).

### Transcriptions validées et diarées

La diarisation ne retarde pas `committed_transcript`. Lorsque la diarisation est activée, cet événement ajoute un entier `segment_index` à partir de zéro :

```json
{
  "message_type": "committed_transcript",
  "segment_index": 0,
  "text": "Hello."
}
```

Chaque validation est suivie d’un événement `diarized_transcript` distinct avec les champs `segment_index`, `text` et `words` correspondants :

```json
{
  "message_type": "diarized_transcript",
  "segment_index": 0,
  "text": "Hello.",
  "words": [
    {
      "text": "Hello.",
      "speaker_id": "speaker_0"
    }
  ]
}
```

Le mot ci-dessus n’affiche que le texte et l’étiquette du locuteur. La structure complète d’un mot utilise les mêmes champs `start`, `end`, `type`, `logprob` et `characters` que la transcription par lots, ainsi que `speaker_id`. Un locuteur non résolu possède un identifiant de locuteur `null`.

Les transcriptions diarées sont envoyées dans l’ordre de validation. Associez-les aux transcriptions validées à l’aide de `segment_index`, plutôt qu’en utilisant le texte ou l’événement reçu suivant. Un `diarized_transcript` est toujours envoyé pour chaque validation, même si l’identification du locuteur échoue ; dans ce cas, les identifiants de locuteur non résolus sont `null`.

### Fusions de locuteurs

Un événement `speakers_merged` signifie que deux identifiants de locuteur renvoient à la même personne :

```json
{
  "message_type": "speakers_merged",
  "from_speaker_id": "speaker_1",
  "to_speaker_id": "speaker_0"
}
```

Remplacez chaque utilisation antérieure de `from_speaker_id` par `to_speaker_id` dans les transcriptions partielles comme diarées. Les identifiants de locuteur ne sont jamais réutilisés. Les fusions peuvent s’enchaîner, appliquez-les donc dans l’ordre de réception : si `speaker_2` fusionne avec `speaker_1`, puis que `speaker_1` fusionne avec `speaker_0`, tous les mots précédents associés à ces deux identifiants doivent être étiquetés `speaker_0`.

Par exemple, appelez ce gestionnaire pour chaque événement reçu. Ici, `transcript_history` stocke chaque transcription partielle et diarée conservée par l’application, y compris les instantanés partiels antérieurs. Chaque fusion met à jour tous les mots stockés sur place, de sorte que les fusions en chaîne mettent également à jour les mots précédemment fusionnés. Affichez les étiquettes de locuteur depuis ce stockage mis à jour ; les étiquettes `null` restent `null`.

```python
transcript_history = []


def handle_event(event):
    if event["message_type"] in ("partial_transcript", "diarized_transcript"):
        transcript_history.append(event)
    elif event["message_type"] == "speakers_merged":
        for transcript in transcript_history:
            for word in transcript.get("words") or []:
                if word.get("speaker_id") == event["from_speaker_id"]:
                    word["speaker_id"] = event["to_speaker_id"]
```

## Limites

* La diarisation est prise en charge uniquement par `scribe_v3_live`. Les autres modèles renvoient une erreur `invalid_request` avec le message `"The 'diarize' parameter is only supported by scribe_v3_live."`, puis ferment la connexion.
* La diarisation ne peut pas être combinée avec `filter_background_audio`. Cette combinaison renvoie une erreur `invalid_request` dont le message contient `"cannot be combined with filter_background_audio"`, puis ferme la connexion.
* Les étiquettes de locuteur peuvent rester non résolues (`null`), et des événements `speakers_merged` ultérieurs peuvent modifier les étiquettes précédentes. Ces événements de fusion sont envoyés uniquement lorsque la diarisation est activée.