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

# Wielokanałowa zamiana mowy na tekst

> **Note**
>
> **Poradnik** · Zakłada, że masz za sobą [krótki przewodnik po Speech to Text ](/docs/pl/eleven-api/guides/cookbooks/speech-to-text).

## Omówienie

Funkcja wielokanałowego Speech to Text pozwala transkrybować pliki audio, w których każdy kanał zawiera innego mówcę. Jest szczególnie przydatna w nagraniach, gdzie mówcy są odseparowani na osobnych kanałach audio, zapewniając czystsze transkrypcje bez potrzeby diarizacji mówców.

Każdy kanał jest przetwarzany niezależnie i automatycznie otrzymuje identyfikator mówcy na podstawie numeru kanału (kanał 0 → `speaker_0`, kanał 1 → `speaker_1` itd.). System wyodrębnia poszczególne kanały z wejściowego pliku audio i transkrybuje je równolegle. Domyślnie API zwraca jedną transkrypcję na kanał; ustaw `multichannel_output_style=combined`, aby otrzymać jedną transkrypcję ze wszystkimi kanałami połączonymi w jedną listę posortowaną według czasu rozpoczęcia, gdzie każde słowo ma tag `channel_index`.

### Typowe zastosowania

* **Nagrania wywiadów stereo** - Prowadzący w lewym kanale, rozmówca w prawym
* **Nagrania podcastów wielościeżkowych** - Każdy uczestnik nagrywany na osobnej ścieżce
* **Nagrania z call center** - Agent i klient na różnych kanałach
* **Nagrania konferencji** - Poszczególni uczestnicy odseparowani na osobnych kanałach
* **Postępowania sądowe** - Wiele stron nagranych na osobnych kanałach

## Wymagania

* Konto ElevenLabs z [kluczem API](https://elevenlabs.io/app/settings/api-keys)
* Wielokanałowy plik audio (WAV, MP3 lub inny obsługiwany format)
* Maksymalnie 5 kanałów na plik audio
* Każdy kanał powinien zawierać tylko jednego mówcę

## Jak to działa

#### Przygotuj wielokanałowe audio

Upewnij się, że mówcy są odseparowani na osobnych kanałach. Funkcja wielokanałowa obsługuje do 5 kanałów, z których każdy jest przypisany do konkretnego mówcy:

* Kanał 0 → `speaker_0`
* Kanał 1 → `speaker_1`
* Kanał 2 → `speaker_2`
* Kanał 3 → `speaker_3`
* Kanał 4 → `speaker_4`

#### Skonfiguruj parametry API

Podczas wysyłania żądania zamiany mowy na tekst musisz ustawić:

* `use_multi_channel`: `true`
* `diarize`: `false` (tryb wielokanałowy rozdziela mówców przez kanały)

Opcjonalnie możesz określić format odpowiedzi:

* `multichannel_output_style`: `separate` (domyślnie) zwraca jedną transkrypcję na kanał. `combined` łączy wszystkie kanały w jedną transkrypcję, której słowa są posortowane według czasu rozpoczęcia, a każde ma `channel_index` — zgodnie ze standardowym formatem odpowiedzi dla pojedynczego kanału. `combined` wymaga znaczników czasu (`timestamps_granularity` nie może mieć wartości `none`) i nie jest obsługiwane przy dostarczaniu przez webhook ani przy wykrywaniu/redagowaniu encji.

Parametru `num_speakers` nie można używać w trybie wielokanałowym, ponieważ liczba mówców jest automatycznie określana przez liczbę kanałów. Tryb wielokanałowy zakłada dokładnie jednego mówcę na kanał. Jeśli będzie ich więcej, wszystkim mówcom w kanale przypisze ten sam identyfikator mówcy.

#### Przetwórz odpowiedź

Domyślnie (`multichannel_output_style=separate`) audio wielokanałowe zwraca inny format odpowiedzi niż audio jednokanałowe:

> **Note**
>
> Jeśli ustawisz `use_multi_channel: true`, ale podasz jednokanałowy (mono) plik audio, otrzymasz
> standardową odpowiedź dla pojedynczego kanału, a nie format wielokanałowy. Format odpowiedzi wielokanałowej
> jest zwracany tylko wtedy, gdy plik audio faktycznie zawiera wiele kanałów.

**`Odpowiedź dla pojedynczego kanału`**

```python title="Odpowiedź dla pojedynczego kanału"
{
  "language_code": "en",
  "language_probability": 0.98,
  "text": "Hello world",
  "words": [...]
}
```

**`Odpowiedź wielokanałowa`**

```python title="Odpowiedź wielokanałowa"
{
  "transcripts": [
    {
      "language_code": "en",
      "language_probability": 0.98,
      "text": "Hello from channel one.",
      "channel_index": 0,
      "words": [...]
    },
    {
      "language_code": "en",
      "language_probability": 0.97,
      "text": "Greetings from channel two.",
      "channel_index": 1,
      "words": [...]
    }
  ]
}
```

**`Połączona odpowiedź (multichannel_output_style=combined)`**

```python title="Połączona odpowiedź (multichannel_output_style=combined)"
{
  "language_code": "en",
  "language_probability": 0.98,
  "text": "Hello from channel one. Greetings from channel two.",
  "words": [
    { "text": "Hello", "start": 0.0, "end": 0.5, "type": "word", "speaker_id": "speaker_0", "channel_index": 0 },
    { "text": "Greetings", "start": 0.6, "end": 1.2, "type": "word", "speaker_id": "speaker_1", "channel_index": 1 }
  ]
}
```

Przy `multichannel_output_style=combined` odpowiedź ma ten sam płaski format co transkrypcja jednokanałowa (`text` i `words` na najwyższym poziomie, bez tablicy `transcripts`), a wszystkie kanały są połączone w jedną listę posortowaną według czasu rozpoczęcia. Każde słowo zawiera `channel_index` (oraz `speaker_id`) wskazujący jego kanał.

## Implementacja

### Podstawowa transkrypcja wielokanałowa

Oto kompletny przykład transkrypcji pliku audio stereo z dwoma mówcami:

**`Python`**

```python title="Python"
from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs(api_key="YOUR_API_KEY")

def transcribe_multichannel(audio_file_path):
    with open(audio_file_path, 'rb') as audio_file:
        result = elevenlabs.speech_to_text.convert(
            file=audio_file,
            model_id='scribe_v2',
            use_multi_channel=True,
            diarize=False,
            timestamps_granularity='word'
        )
    return result

# Process the response

result = transcribe_multichannel('stereo_interview.wav')

if hasattr(result, 'transcripts'): # Multichannel response
    for transcript in result.transcripts:
        channel = transcript.channel_index
        text = transcript.text
        print(f"Channel {channel} (speaker_{channel}): {text}")
    else: # Single channel response (fallback)
        print(f"Text: {result.text}")

```

**`JavaScript`**

```javascript title="JavaScript"
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import fs from "fs";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

async function transcribeMultichannel(audioFilePath) {
  try {
    const audioFile = fs.createReadStream(audioFilePath);

    const result = await elevenlabs.speechToText.convert({
      file: audioFile,
      modelId: "scribe_v2",
      useMultiChannel: true,
      diarize: false,
      timestampsGranularity: "word",
    });

    // With useMultiChannel: true the SDK returns one transcript per channel
    result.transcripts.forEach((transcript) => {
      console.log(`Channel ${transcript.channelIndex}: ${transcript.text}`);
    });

    return result;
  } catch (error) {
    console.error("Error transcribing audio:", error);
    throw error;
  }
}
```

**`cURL`**

```bash title="cURL"
curl -X POST "https://api.elevenlabs.io/v1/speech-to-text" \
  -H "xi-api-key: YOUR_API_KEY" \
  -F "file=@stereo_audio_file.wav" \
  -F "model_id=scribe_v2" \
  -F "use_multi_channel=true" \
  -F "diarize=false" \
  -F "timestamps_granularity=word"
```

### Tworzenie transkrypcji rozmów

Najłatwiej uzyskać transkrypcję rozmowy w kolejności czasowej, ustawiając `multichannel_output_style=combined` — API zwróci pojedynczą listę `words`, już posortowaną według czasu rozpoczęcia, z `channel_index` i `speaker_id` przy każdym słowie:

**`Połączony wynik (zalecane)`**

```python title="Połączony wynik (zalecane)"
with open("stereo_interview.wav", "rb") as audio_file:
    result = elevenlabs.speech_to_text.convert(
        file=audio_file,
        model_id="scribe_v2",
        use_multi_channel=True,
        multichannel_output_style="combined",
        diarize=False,
        timestamps_granularity="word",
    )

for word in result.words:
    if word.type == "word":
        print(f"speaker_{word.channel_index}: {word.text}")
```

Jeśli używasz domyślnego formatu `separate`, możesz zamiast tego połączyć transkrypcje poszczególnych kanałów po stronie klienta:

```python
def create_conversation_transcript(multichannel_result):
    """Create a conversation-style transcript with speaker labels"""
    all_words = []

    if hasattr(multichannel_result, 'transcripts'):
        # Collect all words from all channels
        for transcript in multichannel_result.transcripts:
            for word in transcript.words or []:
                if word.type == 'word':
                    all_words.append({
                        'text': word.text,
                        'start': word.start,
                        'speaker_id': word.speaker_id,
                        'channel': transcript.channel_index
                    })

    # Sort by timestamp
    all_words.sort(key=lambda w: w['start'])

    # Group consecutive words by speaker
    conversation = []
    current_speaker = None
    current_text = []

    for word in all_words:
        if word['speaker_id'] != current_speaker:
            if current_text:
                conversation.append({
                    'speaker': current_speaker,
                    'text': ' '.join(current_text)
                })
            current_speaker = word['speaker_id']
            current_text = [word['text']]
        else:
            current_text.append(word['text'])

    # Add the last segment
    if current_text:
        conversation.append({
            'speaker': current_speaker,
            'text': ' '.join(current_text)
        })

    return conversation

# Format the output
conversation = create_conversation_transcript(result)
for turn in conversation:
    print(f"{turn['speaker']}: {turn['text']}")
```

## Korzystanie z webhooków w trybie wielokanałowym

Transkrypcja wielokanałowa obsługuje [dostarczanie przez webhook](/docs/pl/eleven-api/guides/how-to/speech-to-text/batch/webhooks) przy przetwarzaniu asynchronicznym:

> **Note**
>
> Webhooki zwracają format `separate` (na kanał). `multichannel_output_style=combined` nie jest
> obecnie obsługiwane przy dostarczaniu przez webhook — użyj żądania synchronicznego lub połącz dane
> webhooka dla poszczególnych kanałów po stronie klienta.

```python
from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs(api_key="YOUR_API_KEY")

async def transcribe_multichannel_with_webhook(audio_file_path):
    with open(audio_file_path, 'rb') as audio_file:
        result = await elevenlabs.speech_to_text.convert_async(
            file=audio_file,
            model_id='scribe_v2',
            use_multi_channel=True,
            diarize=False,
            webhook=True  # Enable webhook delivery
        )

    print(f"Transcription started with task ID: {result.task_id}")
    return result.task_id
```

## Obsługa błędów

### Typowe błędy walidacji

#### Ustawienie diarize=true w trybie wielokanałowym

**Błąd**: Tryb wielokanałowy nie obsługuje diarizacji i przypisuje mówców na podstawie
kanału, na którym mówią.

**Rozwiązanie**: W trybie wielokanałowym zawsze ustawiaj `diarize=false`.

#### Podanie parametru num_speakers

**Błąd**: Nie można określić num_speakers, gdy włączone jest use_multi_channel. Liczba mówców
jest automatycznie określana przez liczbę kanałów. **Rozwiązanie**: Usuń parametr `num_speakers`
z żądania.

#### Plik audio z ponad 5 kanałami

**Błąd**: Tryb wielokanałowy obsługuje do 5 kanałów, ale plik audio zawiera X kanałów.

**Rozwiązanie**: Przetwarzaj tylko pierwsze 5 kanałów lub wstępnie przetwórz audio, aby zmniejszyć
liczbę kanałów.

#### Używanie połączonego wyniku bez znaczników czasu

**Błąd**: multichannel_output_style='combined' wymaga znaczników czasu; ustaw timestamps_granularity
na 'word' lub 'character'.

**Rozwiązanie**: Połączony wynik sortuje słowa według czasu, więc ustaw `timestamps_granularity` na `word`
(domyślnie) lub `character`.

#### Używanie połączonego wyniku z webhookami

**Błąd**: multichannel_output_style='combined' nie jest jeszcze obsługiwane przy dostarczaniu przez webhook.

**Rozwiązanie**: Użyj żądania synchronicznego z `combined` albo zachowaj domyślny wynik `separate`
przy webhookach i połącz dane po stronie klienta.

## Dobre praktyki

### Przygotowanie audio

> **Tip**
>
> Aby uzyskać najlepsze wyniki: - Używaj próbkowania 16 kHz dla lepszej wydajności - Przed przetwarzaniem usuń ciche lub nieużywane
> kanały - Upewnij się, że każdy kanał zawiera tylko jednego mówcę - Jeśli możesz, używaj formatów bezstratnych
> (WAV), aby uzyskać najlepszą jakość

### Optymalizacja wydajności

Koszt współbieżności rośnie liniowo wraz z liczbą kanałów. Plik 3-kanałowy trwający 60 sekund ma 3 razy większy koszt współbieżności niż plik jednokanałowy.

Czas przetwarzania audio wielokanałowego możesz oszacować według poniższego wzoru:

$$
Processing\ Time = (D \cdot 0.3) + 2 + (N \cdot 0.5)
$$

Gdzie:

* $D$ = czas trwania pliku w sekundach
* $N$ = liczba kanałów
* $0.3$ = współczynnik szybkości przetwarzania (około 30% czasu rzeczywistego)
* $2$ = stały narzut w sekundach
* $0.5$ = narzut na kanał w sekundach

**Przykład**: Dla 60-sekundowego pliku stereo (2 kanały):

$$
Processing\ Time = (60 \cdot 0.3) + 2 + (2 \cdot 0.5) = 18 + 2 + 1 = 21\ seconds
$$

### Zużycie pamięci

W przypadku dużych plików wielokanałowych rozważ strumieniowanie lub dzielenie na części:

**`Python`**

```python title="Python"
def process_large_multichannel_file(file_path, chunk_duration=300):
    """Process large files in chunks (5-minute segments)"""

    from pydub import AudioSegment
    from elevenlabs import ElevenLabs
    import os

    elevenlabs = ElevenLabs(api_key="YOUR_API_KEY")
    audio = AudioSegment.from_file(file_path)
    duration_ms = len(audio)
    chunk_size_ms = chunk_duration * 1000

    all_transcripts = []

    for start_ms in range(0, duration_ms, chunk_size_ms):
        end_ms = min(start_ms + chunk_size_ms, duration_ms)

        # Extract chunk
        chunk = audio[start_ms:end_ms]
        chunk_file = f"temp_chunk_{start_ms}.wav"
        chunk.export(chunk_file, format="wav")

        # Transcribe chunk using SDK
        with open(chunk_file, 'rb') as audio_file:
            result = elevenlabs.speech_to_text.convert(
                file=audio_file,
                model_id='scribe_v2',
                use_multi_channel=True,
                diarize=False,
                timestamps_granularity='word'
            )

        # Adjust timestamps
        if hasattr(result, 'transcripts'):
            for transcript in result.transcripts:
                for word in transcript.words or []:
                    word.start += start_ms / 1000
                    word.end += start_ms / 1000
            all_transcripts.extend(result.transcripts)

        # Clean up
        os.remove(chunk_file)

    return all_transcripts

```

**`JavaScript`**

```javascript title="JavaScript"
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { exec } from "child_process";
import fs from "fs";
import path from "path";
import { promisify } from "util";

const execAsync = promisify(exec);
const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

async function processLargeMultichannelFile(filePath, chunkDuration = 300) {
  /**
   * Process large files in chunks (5-minute segments)
   * Requires ffmpeg to be installed
   */

  // Get audio duration using ffprobe
  const { stdout } = await execAsync(
    `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${filePath}"`
  );
  const durationSeconds = parseFloat(stdout);

  const allTranscripts = [];

  for (let startSeconds = 0; startSeconds < durationSeconds; startSeconds += chunkDuration) {
    const endSeconds = Math.min(startSeconds + chunkDuration, durationSeconds);
    const chunkFile = path.join(path.dirname(filePath), `temp_chunk_${startSeconds}.wav`);

    // Extract chunk using ffmpeg
    await execAsync(
      `ffmpeg -i "${filePath}" -ss ${startSeconds} -t ${chunkDuration} -c:a pcm_s16le "${chunkFile}" -y`
    );

    try {
      // Transcribe chunk
      const audioFile = fs.createReadStream(chunkFile);
      const result = await elevenlabs.speechToText.convert({
        file: audioFile,
        modelId: "scribe_v2",
        useMultiChannel: true,
        diarize: false,
        timestampsGranularity: "word",
      });

      // Adjust timestamps
      if (result.transcripts) {
        for (const transcript of result.transcripts) {
          for (const word of transcript.words || []) {
            word.start += startSeconds;
            word.end += startSeconds;
          }
        }
        allTranscripts.push(...result.transcripts);
      }
    } finally {
      // Clean up
      fs.unlinkSync(chunkFile);
    }
  }

  return { transcripts: allTranscripts };
}
```

## FAQ

#### Co jeśli moje audio ma więcej niż 5 kanałów?

API zwróci błąd. Musisz wybrać 5 kanałów do wysłania do API
lub zmiksować część kanałów przed wysłaniem ich do API.

#### Czy mogę przetwarzać audio mono w trybie wielokanałowym?

Tak, ale nie jest to potrzebne. Jeśli wyślesz audio mono z `use_multi_channel=true`, otrzymasz
standardową odpowiedź dla pojedynczego kanału, a nie format wielokanałowy.

#### Czy mogę otrzymać jedną połączoną transkrypcję zamiast osobnych transkrypcji dla kanałów?

Tak. Ustaw `multichannel_output_style=combined`, aby otrzymać pojedynczą transkrypcję ze wszystkimi kanałami
połączonymi i posortowanymi według czasu rozpoczęcia, gdzie każde słowo ma tag `channel_index`. Jest to zgodne ze
standardowym formatem odpowiedzi dla pojedynczego kanału. Wymaga znaczników czasu i nie jest dostępne przy dostarczaniu przez
webhook.

#### Jak są przypisywane identyfikatory mówców?

Identyfikatory mówców są deterministyczne i zależą od numeru kanału: kanał 0 otrzymuje speaker_0, kanał 1
otrzymuje speaker_1 itd.

#### Czy kanały mogą mieć różne języki?

Tak, każdy kanał jest przetwarzany niezależnie i może wykrywać różne języki. Wykrywanie języka
odbywa się osobno dla każdego kanału. Przy `multichannel_output_style=combined` `language_code` na najwyższym poziomie
odzwierciedla kanał wykryty z największą pewnością, a każde słowo nadal zawiera
`channel_index`.

## Następne kroki

#### [Dokumentacja API](/docs/pl/api-reference/speech-to-text)

Pełna dokumentacja API Speech to Text i opis parametrów.

#### [Webhooki](/docs/pl/eleven-api/guides/how-to/speech-to-text/batch/webhooks)

Otrzymuj wyniki transkrypcji asynchronicznie przez webhook.