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

# Streaming zamiany tekstu na mowę

Ten przewodnik omawia trzy podejścia: generowanie mowy jako pliku, bezpośrednie przesyłanie strumieniowe odpowiedzi audio oraz opcjonalne przesyłanie wygenerowanego audio do zasobnika AWS S3, aby udostępnić je przez podpisany URL.

> **Note**
>
> Ten przewodnik zakłada, że masz już [skonfigurowany klucz API i SDK](/docs/pl/eleven-api/quickstart). Jeśli jeszcze tego nie zrobiłeś, najpierw ukończ
> szybki start. Opcjonalna sekcja przesyłania do S3 wymaga też konta AWS
> z dostępem do S3.

> **Tip**
>
> Chcesz wiedzieć, dlaczego streaming działa właśnie tak? [Jak działa streaming audio](/docs/pl/eleven-api/concepts/audio-streaming) szczegółowo wyjaśnia protokół, buforowanie i
> kompromisy związane z opóźnieniami.

## Zamiana tekstu na mowę (plik)

Aby zamienić tekst na mowę i zapisać ją jako plik, użyjemy metody `convert` z SDK ElevenLabs, a następnie zapiszemy ją lokalnie jako plik `.mp3`.

**`Python`**

```python Python

import os
import uuid
from dotenv import load_dotenv
from elevenlabs import VoiceSettings
from elevenlabs.client import ElevenLabs

load_dotenv()

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
elevenlabs = ElevenLabs(
    api_key=ELEVENLABS_API_KEY,
)


def text_to_speech_file(text: str) -> str:
    # Calling the text_to_speech conversion API with detailed parameters
    response = elevenlabs.text_to_speech.convert(
        voice_id="pNInz6obpgDQGcFmaJgB", # Adam pre-made voice
        output_format="mp3_22050_32",
        text=text,
        model_id="eleven_flash_v2_5", # use the flash model for low latency
        # Optional voice settings that allow you to customize the output
        voice_settings=VoiceSettings(
            stability=0.0,
            similarity_boost=1.0,
            style=0.0,
            use_speaker_boost=True,
            speed=1.0,
        ),
    )

    # uncomment the line below to play the audio back
    # play(response)

    # Generating a unique file name for the output MP3 file
    save_file_path = f"{uuid.uuid4()}.mp3"

    # Writing the audio to a file
    with open(save_file_path, "wb") as f:
        for chunk in response:
            if chunk:
                f.write(chunk)

    print(f"{save_file_path}: A new audio file was saved successfully!")

    # Return the path of the saved audio file
    return save_file_path

```

**`TypeScript`**

```typescript TypeScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import * as dotenv from "dotenv";
import { writeFile } from "node:fs/promises";
import { v4 as uuid } from "uuid";

dotenv.config();

const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;

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

export const createAudioFileFromText = async (text: string): Promise<string> => {
  const audio = await elevenlabs.textToSpeech.convert("JBFqnCBsd6RMkjVDRZzb", {
    modelId: "eleven_v4",
    text,
    outputFormat: "mp3_44100_128",
    // Optional voice settings that allow you to customize the output
    voiceSettings: {
      stability: 0,
      similarityBoost: 0,
      useSpeakerBoost: true,
      speed: 1.0,
    },
  });

  const fileName = `${uuid()}.mp3`;
  await writeFile(fileName, Buffer.from(await new Response(audio).arrayBuffer()));
  return fileName;
};
```

Następnie możesz uruchomić tę funkcję za pomocą:

**`Python`**

```python Python
text_to_speech_file("Hello World")
```

**`TypeScript`**

```typescript TypeScript
await createAudioFileFromText("Hello World");
```

## Zamiana tekstu na mowę (streaming)

Jeśli wolisz przesyłać audio bezpośrednio, bez zapisywania go do pliku, możesz użyć funkcji streamingu.

**`Python`**

```python Python

import os
from typing import IO
from io import BytesIO
from dotenv import load_dotenv
from elevenlabs import VoiceSettings
from elevenlabs.client import ElevenLabs

load_dotenv()

ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
elevenlabs = ElevenLabs(
    api_key=ELEVENLABS_API_KEY,
)


def text_to_speech_stream(text: str) -> IO[bytes]:
    # Perform the text-to-speech conversion
    response = elevenlabs.text_to_speech.stream(
        voice_id="pNInz6obpgDQGcFmaJgB", # Adam pre-made voice
        output_format="mp3_22050_32",
        text=text,
        model_id="eleven_multilingual_v2",
        # Optional voice settings that allow you to customize the output
        voice_settings=VoiceSettings(
            stability=0.0,
            similarity_boost=1.0,
            style=0.0,
            use_speaker_boost=True,
            speed=1.0,
        ),
    )

    # Create a BytesIO object to hold the audio data in memory
    audio_stream = BytesIO()

    # Write each chunk of audio data to the stream
    for chunk in response:
        if chunk:
            audio_stream.write(chunk)

    # Reset stream position to the beginning
    audio_stream.seek(0)

    # Return the stream for further use
    return audio_stream

```

**`TypeScript`**

```typescript TypeScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import * as dotenv from "dotenv";

dotenv.config();

const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;

if (!ELEVENLABS_API_KEY) {
  throw new Error("Missing ELEVENLABS_API_KEY in environment variables");
}

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

export const createAudioStreamFromText = async (text: string): Promise<Buffer> => {
  const audioStream = await elevenlabs.textToSpeech.stream("JBFqnCBsd6RMkjVDRZzb", {
    modelId: "eleven_v4",
    text,
    outputFormat: "mp3_44100_128",
    // Optional voice settings that allow you to customize the output
    voiceSettings: {
      stability: 0,
      similarityBoost: 1.0,
      useSpeakerBoost: true,
      speed: 1.0,
    },
  });

  const chunks: Buffer[] = [];
  for await (const chunk of audioStream) {
    chunks.push(chunk);
  }

  const content = Buffer.concat(chunks);
  return content;
};
```

Następnie możesz uruchomić tę funkcję za pomocą:

**`Python`**

```python Python
text_to_speech_stream("This is James")
```

**`TypeScript`**

```typescript TypeScript
await createAudioStreamFromText("This is James");
```

## Dodatkowo — przesyłanie do AWS S3 i uzyskiwanie bezpiecznego linku do udostępniania

Gdy dane audio zostaną utworzone jako plik lub strumień, możesz chcieć udostępnić je użytkownikom. Możesz przesłać je do zasobnika AWS S3 i wygenerować bezpieczny link do udostępniania.

#### Tworzenie poświadczeń AWS

Aby przesłać dane do S3, musisz dodać identyfikator klucza dostępu AWS, tajny klucz dostępu i nazwę regionu AWS do pliku `.env`. Aby znaleźć te dane, wykonaj poniższe kroki:

1. Zaloguj się do konsoli zarządzania AWS: przejdź na stronę główną AWS i zaloguj się na swoje konto.

![](/docs/_fern-img/e9f1f1b1950962c3d67ea25a0593ca989d33c9f49b641e22eb3f861fc72735e3.webp)

2. Otwórz panel IAM (Identity and Access Management): IAM znajdziesz w menu usług, w sekcji „Security, Identity, & Compliance”. Panel IAM bezpiecznie zarządza dostępem do usług AWS.

![](/docs/_fern-img/d6fa7e75879e7537693c4edde16d0ac5face78d72b00de50743a754c0681a5e3.webp)

3. Utwórz nowego użytkownika (jeśli to konieczne): w panelu IAM wybierz „Users”, a następnie „Add user”. Wpisz nazwę użytkownika.

![](/docs/_fern-img/47b05ffda6925e4e14147aadc296d7c86cbd3340aaa1025083f1e1464b230f51.webp)

4. Ustaw uprawnienia: przypisz zasady bezpośrednio do użytkownika, zależnie od poziomu dostępu, który chcesz przyznać. Do przesyłania do S3 możesz użyć zasady AmazonS3FullAccess. Dobrą praktyką jest jednak przyznawanie minimalnych uprawnień niezbędnych do wykonania zadania. Możesz utworzyć własną zasadę, która pozwala tylko na konieczne działania w zasobniku S3.

![](/docs/_fern-img/4b88bba4f5bb1509aa087a1ab5cc8068a274b17d8887c563f050b77e8438bb94.webp)

5. Sprawdź ustawienia i utwórz użytkownika: sprawdź ustawienia i utwórz użytkownika. Po utworzeniu zobaczysz identyfikator klucza dostępu i tajny klucz dostępu. Pobierz i bezpiecznie zapisz te dane — po tym kroku nie będzie można ponownie pobrać tajnego klucza dostępu.

![](/docs/_fern-img/27dcdff3681522cf936ff6bfb81cf216ada1fe401c7c1dbd10e58cead8a48abc.webp)

6. Pobierz nazwę regionu AWS, np. us-east-1.

![](/docs/_fern-img/016bc11c2f040942b215366c5fc9ac8e01f6261f5ebd44a3456d4b7ba97e9ae8.webp)

Jeśli nie masz zasobnika AWS S3, utwórz nowy, wykonując te kroki:

1. Otwórz panel S3: S3 znajdziesz w menu usług, w sekcji „Storage”.

![](/docs/_fern-img/d2455fa92ce6dfa705c3b91144fe22539fae1611848cb8e3cc2dac20e57db4e7.webp)

2. Utwórz nowy zasobnik: w panelu S3 kliknij przycisk „Create bucket”.

![](/docs/_fern-img/3b7d5bdb6559e8511445b41b1bbdeed3f6674791cf23021a30ccb5aa8143be28.webp)

3. Wpisz nazwę zasobnika i kliknij przycisk „Create bucket”. Pozostałe opcje zasobnika możesz pozostawić domyślne. Nowo dodany zasobnik pojawi się na liście.

![](/docs/_fern-img/68d23f21bec1e3aa70b18f09c40c9bdace5ff0dd63edc17c6807e7ddac75758d.webp)![](/docs/_fern-img/63f7af93d4a73fab3011853c8393c954400d9f344a5811ec90b86d6c69b2ec16.webp)

#### Instalowanie AWS SDK i dodawanie poświadczeń

Zainstaluj `boto3`, aby korzystać z usług AWS za pomocą `pip` i `npm`.

**`Python`**

```bash Python
pip install boto3
```

**`TypeScript`**

```bash TypeScript
npm install @aws-sdk/client-s3
npm install @aws-sdk/s3-request-presigner
```

Następnie dodaj zmienne środowiskowe do pliku `.env`:

```
AWS_ACCESS_KEY_ID=your_aws_access_key_id_here
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key_here
AWS_REGION_NAME=your_aws_region_name_here
AWS_S3_BUCKET_NAME=your_s3_bucket_name_here
```

#### Przesyłanie do AWS S3 i generowanie podpisanego URL

Dodaj poniższe funkcje, aby przesłać strumień audio do S3 i wygenerować podpisany URL.

**`s3_uploader.py (Python)`**

```python s3_uploader.py (Python)

import os
import boto3
import uuid

AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
AWS_REGION_NAME = os.getenv("AWS_REGION_NAME")
AWS_S3_BUCKET_NAME = os.getenv("AWS_S3_BUCKET_NAME")

session = boto3.Session(
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    region_name=AWS_REGION_NAME,
)
s3 = session.client("s3")


def generate_presigned_url(s3_file_name: str) -> str:
    signed_url = s3.generate_presigned_url(
        "get_object",
        Params={"Bucket": AWS_S3_BUCKET_NAME, "Key": s3_file_name},
        ExpiresIn=3600,
    )  # URL expires in 1 hour
    return signed_url


def upload_audiostream_to_s3(audio_stream) -> str:
    s3_file_name = f"{uuid.uuid4()}.mp3"  # Generates a unique file name using UUID
    s3.upload_fileobj(audio_stream, AWS_S3_BUCKET_NAME, s3_file_name)

    return s3_file_name

```

**`s3_uploader.ts (TypeScript)`**

```typescript s3_uploader.ts (TypeScript)
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import * as dotenv from "dotenv";
import { v4 as uuid } from "uuid";

dotenv.config();

const { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION_NAME, AWS_S3_BUCKET_NAME } =
  process.env;

if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY || !AWS_REGION_NAME || !AWS_S3_BUCKET_NAME) {
  throw new Error("One or more environment variables are not set. Please check your .env file.");
}

const s3 = new S3Client({
  credentials: {
    accessKeyId: AWS_ACCESS_KEY_ID,
    secretAccessKey: AWS_SECRET_ACCESS_KEY,
  },
  region: AWS_REGION_NAME,
});

export const generatePresignedUrl = async (objectKey: string) => {
  const getObjectParams = {
    Bucket: AWS_S3_BUCKET_NAME,
    Key: objectKey,
    Expires: 3600,
  };
  const command = new GetObjectCommand(getObjectParams);
  const url = await getSignedUrl(s3, command, { expiresIn: 3600 });
  return url;
};

export const uploadAudioStreamToS3 = async (audioStream: Buffer) => {
  const remotePath = `${uuid()}.mp3`;
  await s3.send(
    new PutObjectCommand({
      Bucket: AWS_S3_BUCKET_NAME,
      Key: remotePath,
      Body: audioStream,
      ContentType: "audio/mpeg",
    })
  );
  return remotePath;
};
```

Następnie możesz wywołać funkcję przesyłania ze strumieniem audio z tekstu.

**`Python`**

```python Python
s3_file_name = upload_audiostream_to_s3(audio_stream)
```

**`TypeScript`**

```typescript TypeScript
const s3path = await uploadAudioStreamToS3(stream);
```

Po przesłaniu pliku audio do S3 wygeneruj podpisany URL, aby udostępnić dostęp do pliku. Ten URL będzie ograniczony czasowo, czyli wygaśnie po określonym czasie, dzięki czemu nadaje się do tymczasowego udostępniania.

Teraz możesz wygenerować URL z pliku za pomocą:

**`Python`**

```python Python
signed_url = generate_presigned_url(s3_file_name)
print(f"Signed URL to access the file: {signed_url}")
```

**`TypeScript`**

```typescript TypeScript
const presignedUrl = await generatePresignedUrl(s3path);
console.log("Presigned URL:", presignedUrl);
```

Jeśli chcesz używać pliku wielokrotnie, zapisz ścieżkę pliku S3 w bazie danych, a następnie regeneruj podpisany URL za każdym razem, gdy go potrzebujesz. Nie zapisuj bezpośrednio podpisanego URL, ponieważ wygaśnie.

#### Wszystko razem

Aby połączyć wszystko, możesz użyć poniższego skryptu:

**`main.py (Python)`**

```python main.py (Python)

import os

from dotenv import load_dotenv

load_dotenv()

from text_to_speech_stream import text_to_speech_stream
from s3_uploader import upload_audiostream_to_s3, generate_presigned_url


def main():
    text = "This is James"

    audio_stream = text_to_speech_stream(text)
    s3_file_name = upload_audiostream_to_s3(audio_stream)
    signed_url = generate_presigned_url(s3_file_name)

    print(f"Signed URL to access the file: {signed_url}")


if __name__ == "__main__":
    main()

```

**`index.ts (Typescript)`**

```typescript index.ts (Typescript)
import "dotenv/config";

import { generatePresignedUrl, uploadAudioStreamToS3 } from "./s3_uploader";
import { createAudioFileFromText } from "./text_to_speech_file";
import { createAudioStreamFromText } from "./text_to_speech_stream";

(async () => {
  // save the audio file to disk
  const fileName = await createAudioFileFromText(
    "Today, the sky is exceptionally clear, and the sun shines brightly."
  );

  console.log("File name:", fileName);

  // OR stream the audio, upload to S3, and get a presigned URL
  const stream = await createAudioStreamFromText(
    "Today, the sky is exceptionally clear, and the sun shines brightly."
  );

  const s3path = await uploadAudioStreamToS3(stream);

  const presignedUrl = await generatePresignedUrl(s3path);

  console.log("Presigned URL:", presignedUrl);
})();
```

## Podsumowanie

Wiesz już, jak zamieniać tekst na mowę i generować podpisany URL do udostępniania pliku audio. Ta funkcja daje wiele możliwości dynamicznego tworzenia i udostępniania treści.

Oto kilka przykładów tego, co możesz zbudować.

1. **Podcasty edukacyjne**: twórz spersonalizowane treści edukacyjne dostępne dla uczniów na żądanie. Nauczyciele mogą zamieniać lekcje na audio, przesyłać je do S3 i udostępniać uczniom linki, by nauka poza tradycyjną klasą była ciekawsza.

2. **Funkcje dostępności na stronach internetowych**: zwiększ dostępność strony, oferując treści tekstowe w formacie audio. Dzięki temu informacje na stronach będą bardziej dostępne dla osób z wadami wzroku lub tych, którzy wolą naukę ze słuchu.

3. **Automatyczne wiadomości obsługi klienta**: twórz automatyczne i spersonalizowane wiadomości audio dla obsługi klienta, na przykład odpowiedzi na często zadawane pytania lub aktualizacje zamówień. Zapewnia to ciekawsze doświadczenie niż tradycyjne e-maile tekstowe.

4. **Audiobooki i narracja**: zamieniaj całe książki lub krótkie opowiadania na format audio, oferując odbiorcom nowy sposób na obcowanie z literaturą. Autorzy i wydawcy mogą poszerzyć ofertę treści i dotrzeć do osób, które wolą słuchać niż czytać.

5. **Narzędzia do nauki języków**: twórz pomoce do nauki języków, które oferują lekcje i ćwiczenia audio. Dzięki temu można ćwiczyć wymowę i rozumienie ze słuchu w ukierunkowany sposób.

## Kolejne kroki

#### [Streaming WebSocket](/docs/pl/eleven-api/guides/how-to/websockets/realtime-tts)

Używaj WebSocketów, aby przesyłać tekst do zamiany na mowę w czasie rzeczywistym podczas generowania go przez LLM.

#### [Jak rozumieć opóźnienia](/docs/pl/eleven-api/concepts/latency)

Dowiedz się, co wpływa na opóźnienia i jak skrócić czas do pierwszego audio.