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

# 話者ダイアライゼーション

> **Note**
>
> **ハウツーガイド** ·
> [クライアント側](/docs/ja/eleven-api/guides/how-to/speech-to-text/realtime/client-side-streaming)または
> [サーバー側ストリーミング](/docs/ja/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming)のガイドを完了していることを前提としています。

## 概要

話者ダイアライゼーションは単語に話者IDを割り当て、誰が何を言ったかを区別できるようにします。ダイアライゼーションを有効にすると、部分的な文字起こしに暫定的な話者ラベルが含まれ、確定した各文字起こしの後に個別の`diarized_transcript`イベントが送信されます。オーディオが追加されると、話者ラベルが変わる場合があります。

## ダイアライゼーションの有効化

`model_id=scribe_v3_live`でWebSocket接続を開く際に、ブール値のクエリパラメーター`diarize=true`を設定します。ダイアライゼーションのデフォルト値は`false`です。

以下のサーバー側の例では、接続を開いてイベントを受信します。Pythonでは`websockets`を、TypeScriptでは`ws`と開発依存関係の`@types/ws`をインストールしてください。サーバー環境で`ELEVENLABS_API_KEY`を設定します。例では、このキーを`xi-api-key`ヘッダーで送信します。ブラウザーコードには含めず、サーバー上で管理してください。

これらの例ではオーディオを送信しません。[サーバー側ストリーミングガイド](/docs/ja/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming)のオーディオ生成処理と統合し、イベントを受信しながら、同じ接続で`input_audio_chunk`メッセージを送信してください。例では`pcm_16000`を選択しているため、それに一致するオーディオを使用します。Pythonでは、オーディオ送信タスクと受信ループを並行して実行します。TypeScriptでは、接続が開いた後にオーディオを送信します。

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

## イベントの処理

### 部分的な文字起こし

ダイアライゼーションを有効にすると、各`partial_transcript`にバッチ文字起こしと同じ単語形式の暫定的な`words`が含まれます。各単語の`speaker_id`は、話者が識別されると`speaker_0`、`speaker_1`のように設定され、未解決の間は`null`になります。

これらの単語は暫定的なものとして扱ってください。オーディオが追加されると、話者IDとタイムスタンプが変わる場合があります。まだアラインメントされていない単語にはタイムスタンプがありません（`start`と`end`が`null`または存在しません）。

### 確定済みおよびダイアライズ済みの文字起こし

ダイアライゼーションによって`committed_transcript`が遅延することはありません。ダイアライゼーションを有効にすると、このイベントには0から始まる整数の`segment_index`が追加されます。

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

確定するたびに、一致する`segment_index`、`text`、`words`を含む個別の`diarized_transcript`イベントが続けて送信されます。

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

上記の単語には、テキストと話者ラベルのみが表示されています。完全な単語形式では、バッチ文字起こしと同じ`start`、`end`、`type`、`logprob`、`characters`フィールドが`speaker_id`とともに使用されます。未解決の話者の話者IDは`null`です。

ダイアライズ済みの文字起こしは、確定された順に送信されます。テキストや次に受信したイベントではなく、`segment_index`を使用して確定済みの文字起こしと対応付けてください。話者を識別できなかった場合でも、確定ごとに必ず`diarized_transcript`が送信されます。その場合、未解決の話者IDは`null`です。

### 話者の統合

`speakers_merged`イベントは、2つの話者IDが同じ人物を指していることを意味します。

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

部分的な文字起こしとダイアライズ済みの文字起こしの両方で、以前に使用されたすべての`from_speaker_id`を`to_speaker_id`に置き換えます。話者IDが再利用されることはありません。統合は連鎖する場合があるため、受信順に適用してください。たとえば、`speaker_2`が`speaker_1`に統合され、その後`speaker_1`が`speaker_0`に統合された場合、両方のIDに属する以前の単語はすべて`speaker_0`とラベル付けする必要があります。

たとえば、受信したイベントごとにこのハンドラーを呼び出します。ここでは、`transcript_history`に、過去の部分的なスナップショットを含め、アプリケーションが保持するすべての部分的な文字起こしとダイアライズ済みの文字起こしを保存します。統合のたびに、保存されているすべての単語をその場で更新するため、連鎖した統合でも以前に統合された単語が更新されます。この更新済みのストレージから話者ラベルを表示してください。`null`ラベルは`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"]
```

## 制限事項

* ダイアライゼーションをサポートしているのは`scribe_v3_live`のみです。他のモデルでは、`"The 'diarize' parameter is only supported by scribe_v3_live."`というメッセージを含む`invalid_request`エラーが返され、接続が閉じられます。
* ダイアライゼーションを`filter_background_audio`と組み合わせることはできません。この組み合わせでは、`"cannot be combined with filter_background_audio"`というメッセージを含む`invalid_request`エラーが返され、接続が閉じられます。
* 話者ラベルが未解決（`null`）のままになる場合があり、後から届く`speakers_merged`イベントによって以前のラベルが変更されることもあります。これらの統合イベントは、ダイアライゼーションが有効な場合にのみ送信されます。