> 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.

# Diarizzazione dei parlanti

> **Note**
>
> **Guida pratica** · Presuppone che tu abbia completato la guida sullo
> [streaming lato client](/docs/it/eleven-api/guides/how-to/speech-to-text/realtime/client-side-streaming) o sullo
> [streaming lato server](/docs/it/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming).

## Panoramica

La diarizzazione dei parlanti assegna ID ai parlanti per ogni parola, così puoi distinguere chi ha detto cosa. Con la diarizzazione abilitata, le trascrizioni parziali includono etichette provvisorie dei parlanti e ogni trascrizione confermata è seguita da un evento `diarized_transcript` separato. Le etichette dei parlanti possono cambiare man mano che arriva altro audio.

## Abilitare la diarizzazione

Imposta il parametro query booleano `diarize=true` quando apri una connessione WebSocket con `model_id=scribe_v3_live`. Per impostazione predefinita, la diarizzazione è `false`.

I seguenti esempi lato server aprono una connessione e ricevono eventi. Installa `websockets` per Python oppure `ws` e la dipendenza di sviluppo `@types/ws` per TypeScript. Imposta `ELEVENLABS_API_KEY` nell'ambiente del server; gli esempi la inviano nell'header `xi-api-key`. Mantieni questa chiave sul server, non nel codice del browser.

Questi esempi non inviano audio. Integrali con il tuo produttore di audio dalla [guida sullo streaming lato server](/docs/it/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming): invia messaggi `input_audio_chunk` sulla stessa connessione mentre ricevi gli eventi. Gli esempi selezionano `pcm_16000`, quindi usa un audio corrispondente. In Python, esegui l'attività di invio dell'audio contemporaneamente al ciclo di ricezione; in TypeScript, invia l'audio dopo l'apertura della connessione.

```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);
});
```

## Gestire gli eventi

### Trascrizioni parziali

Con la diarizzazione abilitata, ogni `partial_transcript` include `words` provvisorie con la stessa struttura delle parole della trascrizione batch. Il campo `speaker_id` di ogni parola è `speaker_0`, `speaker_1` e così via quando un parlante viene identificato, oppure `null` finché non viene risolto.

Considera queste parole come provvisorie: gli ID dei parlanti e i timestamp possono cambiare con altro audio. Le parole che non sono ancora state allineate non hanno timestamp (`start` e `end` sono `null` o assenti).

### Trascrizioni confermate e diarizzate

La diarizzazione non ritarda `committed_transcript`. Con la diarizzazione abilitata, questo evento aggiunge un valore intero `segment_index` con indice a partire da zero:

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

Ogni conferma è seguita da un evento `diarized_transcript` separato con `segment_index`, `text` e `words` corrispondenti:

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

La parola sopra mostra soltanto il testo e l'etichetta del parlante. La struttura completa della parola usa gli stessi campi `start`, `end`, `type`, `logprob` e `characters` della trascrizione batch, insieme a `speaker_id`. Un parlante non risolto ha un ID parlante `null`.

Le trascrizioni diarizzate vengono inviate nell'ordine di conferma. Associale alle trascrizioni confermate usando `segment_index`, anziché il testo o l'evento ricevuto successivo. Viene sempre inviato un `diarized_transcript` per ogni conferma, anche se l'identificazione del parlante non riesce; in tal caso, gli ID dei parlanti non risolti sono `null`.

### Unioni di parlanti

Un evento `speakers_merged` indica che due ID parlante si riferiscono alla stessa persona:

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

Sostituisci ogni uso precedente di `from_speaker_id` con `to_speaker_id` sia nelle trascrizioni parziali sia in quelle diarizzate. Gli ID dei parlanti non vengono mai riutilizzati. Le unioni possono concatenarsi, quindi applicale nell'ordine di ricezione: se `speaker_2` viene unito a `speaker_1` e poi `speaker_1` viene unito a `speaker_0`, tutte le parole precedenti di entrambi gli ID devono infine avere l'etichetta `speaker_0`.

Ad esempio, chiama questo gestore per ogni evento ricevuto. Qui, `transcript_history` memorizza tutte le trascrizioni parziali e diarizzate conservate dall'applicazione, incluse le istantanee parziali precedenti. Ogni unione aggiorna tutte le parole memorizzate in loco, quindi le unioni concatenate aggiornano anche le parole unite in precedenza. Visualizza le etichette dei parlanti da questo archivio aggiornato; le etichette `null` rimangono `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"]
```

## Limitazioni

* La diarizzazione è supportata soltanto da `scribe_v3_live`. Gli altri modelli restituiscono un errore `invalid_request` con il messaggio `"The 'diarize' parameter is only supported by scribe_v3_live."`, quindi chiudono la connessione.
* La diarizzazione non può essere combinata con `filter_background_audio`. Questa combinazione restituisce un errore `invalid_request` il cui messaggio contiene `"cannot be combined with filter_background_audio"`, quindi chiude la connessione.
* Le etichette dei parlanti possono rimanere non risolte (`null`) e gli eventi `speakers_merged` successivi possono rivedere le etichette precedenti. Questi eventi di unione vengono inviati soltanto quando la diarizzazione è abilitata.