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

# Streama text till tal

Den här guiden beskriver tre metoder: att generera tal som en fil, att streama ljudsvaret direkt och att valfritt ladda upp genererat ljud till en AWS S3-bucket för delning via en signerad URL.

> **Note**
>
> Den här guiden förutsätter att du har [konfigurerat din API-nyckel och SDK](/docs/sv/eleven-api/quickstart). Slutför
> snabbstarten först om du inte redan har gjort det. Det valfria avsnittet om S3-uppladdning kräver också ett AWS-konto
> med åtkomst till S3.

> **Tip**
>
> Undrar du varför streaming fungerar som den gör? [Så fungerar ljud- streaming](/docs/sv/eleven-api/concepts/audio-streaming) förklarar protokollet, buffring och
> avvägningar kring latens på djupet.

## Omvandla text till tal (fil)

För att omvandla text till tal och spara det som en fil använder vi metoden `convert` i ElevenLabs SDK och sparar det sedan lokalt som en `.mp3`-fil.

**`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 { createWriteStream } from "fs";
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> => {
  return new Promise<string>(async (resolve, reject) => {
    try {
      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`;
      const fileStream = createWriteStream(fileName);

      audio.pipe(fileStream);
      fileStream.on("finish", () => resolve(fileName)); // Resolve with the fileName
      fileStream.on("error", reject);
    } catch (error) {
      reject(error);
    }
  });
};
```

Du kan sedan köra funktionen med:

**`Python`**

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

**`TypeScript`**

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

## Omvandla text till tal (streaming)

Om du föredrar att streama ljudet direkt utan att spara det som en fil kan du använda vår streamingfunktion.

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

Du kan sedan köra funktionen med:

**`Python`**

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

**`TypeScript`**

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

## Bonus – ladda upp till AWS S3 och hämta en säker delningslänk

När dina ljuddata har skapats som antingen en fil eller en ström kanske du vill dela dem med dina användare. Ett sätt är att ladda upp dem till en AWS S3-bucket och generera en säker delningslänk.

#### Skapa dina AWS-autentiseringsuppgifter

För att ladda upp data till S3 behöver du lägga till ditt AWS-åtkomstnyckel-ID, din hemliga åtkomstnyckel och AWS-regionens namn i din `.env`-fil. Följ dessa steg för att hitta autentiseringsuppgifterna:

1. Logga in på AWS Management Console: Gå till AWS startsida och logga in med ditt konto.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/e9f1f1b1950962c3d67ea25a0593ca989d33c9f49b641e22eb3f861fc72735e3/assets/images/cookbooks/aws_console_login.webp)

2. Öppna IAM-instrumentpanelen (Identity and Access Management): Du hittar IAM under "Security, Identity, & Compliance" i tjänstemenyn. IAM-instrumentpanelen hanterar åtkomst till dina AWS-tjänster på ett säkert sätt.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/d6fa7e75879e7537693c4edde16d0ac5face78d72b00de50743a754c0681a5e3/assets/images/cookbooks/aws_iam_dashboard.webp)

3. Skapa en ny användare (vid behov): Välj "Users" och sedan "Add user" på IAM-instrumentpanelen. Ange ett användarnamn.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/47b05ffda6925e4e14147aadc296d7c86cbd3340aaa1025083f1e1464b230f51/assets/images/cookbooks/aws_iam_add_user.webp)

4. Ställ in behörigheter: koppla policyer direkt till användaren utifrån den åtkomstnivå du vill ge. För S3-uppladdningar kan du använda policyn AmazonS3FullAccess. Bästa praxis är dock att ge minsta möjliga behörighet, alltså de minimala behörigheter som krävs för att utföra en uppgift. Du kanske vill skapa en anpassad policy som endast tillåter nödvändiga åtgärder i din S3-bucket.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/4b88bba4f5bb1509aa087a1ab5cc8068a274b17d8887c563f050b77e8438bb94/assets/images/cookbooks/aws_iam_set_permission.webp)

5. Granska och skapa användaren: Granska dina inställningar och skapa användaren. När användaren har skapats får du ett åtkomstnyckel-ID och en hemlig åtkomstnyckel. Se till att ladda ner och spara dessa uppgifter på ett säkert sätt; den hemliga åtkomstnyckeln kan inte hämtas igen efter detta steg.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/27dcdff3681522cf936ff6bfb81cf216ada1fe401c7c1dbd10e58cead8a48abc/assets/images/cookbooks/aws_access_secret_key.webp)

6. Hämta AWS-regionens namn: t.ex. us-east-1

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/016bc11c2f040942b215366c5fc9ac8e01f6261f5ebd44a3456d4b7ba97e9ae8/assets/images/cookbooks/aws_region_name.webp)

Om du inte har en AWS S3-bucket behöver du skapa en genom att följa dessa steg:

1. Öppna S3-instrumentpanelen: Du hittar S3 under "Storage" i tjänstemenyn.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/d2455fa92ce6dfa705c3b91144fe22539fae1611848cb8e3cc2dac20e57db4e7/assets/images/cookbooks/aws_s3_dashboard.webp)

2. Skapa en ny bucket: Klicka på knappen "Create bucket" på S3-instrumentpanelen.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/3b7d5bdb6559e8511445b41b1bbdeed3f6674791cf23021a30ccb5aa8143be28/assets/images/cookbooks/aws_s3_create_bucket.webp)

3. Ange ett bucket-namn och klicka på knappen "Create bucket". Du kan låta de andra alternativen för bucket vara standardinställda. Den nyligen tillagda bucketen visas i listan.

![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/68d23f21bec1e3aa70b18f09c40c9bdace5ff0dd63edc17c6807e7ddac75758d/assets/images/cookbooks/aws_s3_enter_bucket_name.webp)![](/docs/_fern-files/elevenlabs.docs.buildwithfern.com/63f7af93d4a73fab3011853c8393c954400d9f344a5811ec90b86d6c69b2ec16/assets/images/cookbooks/aws_s3_bucket_list.webp)

#### Installera AWS SDK och lägg till autentiseringsuppgifterna

Installera `boto3` för att interagera med AWS-tjänster med `pip` och `npm`.

**`Python`**

```bash Python
pip install boto3
```

**`TypeScript`**

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

Lägg sedan till miljövariablerna i `.env`-filen så här:

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

#### Ladda upp till AWS S3 och generera den signerade URL:en

Lägg till följande funktioner för att ladda upp ljudströmmen till S3 och generera en signerad 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;
};
```

Du kan sedan anropa uppladdningsfunktionen med ljudströmmen från texten.

**`Python`**

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

**`TypeScript`**

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

När du har laddat upp ljudfilen till S3 genererar du en signerad URL för att dela åtkomst till filen. Den här URL:en är tidsbegränsad, vilket innebär att den upphör att gälla efter en viss tid och därför är säker för tillfällig delning.

Du kan nu generera en URL från en fil med:

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

Om du vill använda filen flera gånger bör du lagra S3-filsökvägen i din databas och sedan generera den signerade URL:en på nytt varje gång du behöver den, i stället för att spara den signerade URL:en direkt eftersom den upphör att gälla.

#### Sätt ihop allt

För att sätta ihop allt kan du använda följande skript:

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

## Slutsats

Du vet nu hur du omvandlar text till tal och genererar en signerad URL för att dela ljudfilen. Funktionen öppnar många möjligheter att skapa och dela innehåll dynamiskt.

Här är några exempel på vad du kan bygga med detta.

1. **Utbildningspodcastar**: Skapa personanpassat utbildningsinnehåll som elever kan komma åt vid behov. Lärare kan omvandla sina lektioner till ljudformat, ladda upp dem till S3 och dela länkarna med eleverna för en mer engagerande inlärningsupplevelse utanför det traditionella klassrummet.

2. **Tillgänglighetsfunktioner för webbplatser**: Förbättra webbplatsers tillgänglighet genom att erbjuda textinnehåll i ljudformat. Det kan göra information på webbplatser mer tillgänglig för personer med synnedsättning eller för dem som föredrar auditiv inlärning.

3. **Automatiserade kundsupportmeddelanden**: Skapa automatiserade och personanpassade ljudmeddelanden för kundsupport, till exempel vanliga frågor eller orderuppdateringar. Det kan ge en mer engagerande kundupplevelse jämfört med traditionella e-postmeddelanden i textformat.

4. **Ljudböcker och berättarröst**: Omvandla hela böcker eller noveller till ljudformat och ge publiken ett nytt sätt att ta del av litteratur. Författare och förlag kan bredda sitt innehållserbjudande och nå personer som föredrar att lyssna framför att läsa.

5. **Språkinlärningsverktyg**: Utveckla hjälpmedel för språkinlärning som ger användare ljudlektioner och övningar. Det gör det möjligt att träna uttal och hörförståelse på ett riktat sätt.

## Nästa steg

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

Använd WebSockets för att streama text till tal i realtid medan den genereras av en LLM.

#### [Förstå latens](/docs/sv/eleven-api/concepts/latency)

Lär dig vad som bidrar till latens och hur du minimerar tiden till första ljudet.