跳到正文
DEV Community· VoiceDeveloper·· 3 小時前AI 評分42

如何用 ElevenLabs 和 Python 建立文字轉語音應用程式

Build a Text-to-Speech App with ElevenLabs and Python

AI 導讀

ElevenLabs 和 Python 可用來建立文字轉語音應用程式,透過 API 將文字轉成 MP3 音訊並播放。文章示範非同步合成、語音克隆及遇到 429 Too Many Requests 時的重試處理,並展示如何用 FastAPI 將功能部署為微服務。

正文

Why Text‑to‑Speech Matters Today

If you’ve ever built a chatbot, an accessibility feature, or a voice‑enabled game, you know that a natural‑sounding voice can turn a static experience into something engaging and human‑like. Modern TTS engines are no longer limited to robotic monotones – they can capture emotion, intonation, and even mimic a specific speaker’s style.

That’s where ElevenLabs shines. Their API delivers high‑quality neural voices that are easy to integrate, and the pricing model works well for both hobby projects and production apps. In this post we’ll walk through building a simple Python app that sends text to ElevenLabs, receives an audio file, and plays it back. By the end you’ll have a reusable script you can drop into any project.


Prerequisites

What you need Why
Python 3.8+ The example uses f‑strings and asyncio.
pip To install the required packages.
ElevenLabs API key You’ll need an account; sign up via the affiliate link: https://try.elevenlabs.io/kr07zfuqn1bp
A speaker or headphones To hear the generated audio.

1️⃣ Grab Your ElevenLabs API Key

  1. Visit the signup page (the link above) and create a free account.
  2. After confirming your email, go to Dashboard → API Keys.
  3. Click Create new key, give it a name, and copy the generated token.

Keep this token secret – treat it like a password.


2️⃣ Install the Required Packages

pip install httpx python-dotenv pydub
  • httpx – a modern async HTTP client.
  • python-dotenv – loads environment variables from a .env file.
  • pydub – convenient for playing or converting the returned MP3. (You’ll also need ffmpeg installed on your system; on macOS you can use brew install ffmpeg, on Ubuntu sudo apt-get install ffmpeg.)

Create a .env file in your project root:

ELEVENLABS_API_KEY=your_api_key_here

3️⃣ The Core TTS Function

Below is a minimal async function that talks to ElevenLabs. It accepts the text you want spoken, the voice ID (we’ll use the default “Rachel” for now), and returns the path to a saved MP3 file.

import os
import httpx
from pathlib import Path
from dotenv import load_dotenv

load_dotenv()
API_KEY = os.getenv("ELEVENLABS_API_KEY")
BASE_URL = "https://api.elevenlabs.io/v1"

async def synthesize(
    text: str,
    voice_id: str = "EXAVITQu4vr4xnSDxMaL",  # default voice (Rachel)
    output_path: Path = Path("output.mp3"),
) -> Path:
    url = f"{BASE_URL}/text-to-speech/{voice_id}"
    headers = {
        "xi-api-key": API_KEY,
        "Content-Type": "application/json",
    }
    payload = {
        "text": text,
        "model_id": "eleven_monolingual_v1",
        "voice_settings": {
            "stability": 0.75,
            "similarity_boost": 0.75,
        },
    }

    async with httpx.AsyncClient(timeout=30.0) as client:
        response = await client.post(url, json=payload, headers=headers)

    response.raise_for_status()
    # The API streams raw audio bytes (MP3)
    output_path.write_bytes(response.content)
    return output_path

What’s happening?

  • We post JSON to /text-to-speech/{voice_id}.
  • model_id selects the neural model; eleven_monolingual_v1 is the most balanced for English.
  • stability and similarity_boost let you tweak how consistent the voice sounds vs. how expressive it is.

Feel free to experiment – a higher stability makes the voice more monotone, while a higher similarity_boost pushes it toward the reference voice.


4️⃣ Playing the Result

from pydub import AudioSegment
from pydub.playback import play

def play_audio(file_path: Path):
    audio = AudioSegment.from_file(file_path, format="mp3")
    play(audio)

5️⃣ Putting It All Together

import asyncio
from pathlib import Path

async def main():
    text = (
        "Hello, fellow developer! "
        "With ElevenLabs, you can turn any string into a natural‑sounding voice."
    )
    output_file = Path("speech.mp3")

    print("Generating speech…")
    await synthesize(text, output_path=output_file)
    print(f"Saved to {output_file}")

    print("Playing back…")
    play_audio(output_file)

if __name__ == "__main__":
    asyncio.run(main())

Run the script:

python tts_demo.py

You should hear the phrase spoken in a clear, human‑like voice. 🎉


6️⃣ Going Beyond: Voice Cloning

ElevenLabs also offers voice cloning – you can upload a few minutes of a speaker’s recordings and generate a custom voice ID. The workflow is:

  1. Upload audio samples via the /voices/add endpoint (or via the web UI).
  2. Wait for processing – the API returns a voice_id once the model is ready.
  3. Use that voice_id in the synthesize function above.

Here’s a quick curl example for uploading a sample (replace YOUR_API_KEY and sample.wav with your values):

curl -X POST "https://api.elevenlabs.io/v1/voices/add" \
  -H "xi-api-key: YOUR_API_KEY" \
  -F "name=MyCustomVoice" \
  -F "files[]=@sample.wav"

The response contains:

{
  "voice_id": "abc123def456",
  "name": "MyCustomVoice",
  "preview_url": "https://..."
}

Now just pass "abc123def456" as the voice_id to synthesize and you’ll hear your voice reading the text. This is a game‑changer for personalized assistants, audiobooks, and dubbing.


7️⃣ Error Handling & Rate Limits

ElevenLabs enforces a per‑minute request quota based on your plan. If you exceed it, you’ll receive a 429 Too Many Requests response. A simple retry strategy can keep your app smooth:

import time

async def safe_synthesize(*args, **kwargs):
    retries = 3
    backoff = 2
    for attempt in range(retries):
        try:
            return await synthesize(*args, **kwargs)
        except httpx.HTTPStatusError as exc:
            if exc.response.status_code == 429 and attempt < retries - 1:
                wait = backoff ** attempt
                print(f"Rate limited, sleeping {wait}s…")
                time.sleep(wait)
                continue
            raise

Wrap your calls with await safe_synthesize(...) to automatically back‑off on throttling.


8️⃣ Deploying to the Cloud

If you want to expose this TTS capability as a micro‑service, Flask or FastAPI work nicely:

from fastapi import FastAPI, Body
from fastapi.responses import FileResponse

app = FastAPI()

@app.post("/speak")
async def speak(text: str = Body(...)):
    out_file = await safe_synthesize(text)
    return FileResponse(out_file, media_type="audio/mpeg")

Deploy to Render, Fly.io, or any container platform, and you’ll have an HTTP endpoint that turns any string into speech on demand.


9️⃣ Tips for Production

Tip Reason
Cache results Many apps reuse the same phrases (e.g., “Welcome back”). Store the MP3 locally to avoid unnecessary API calls.
Validate input length The free tier caps requests at 2 000 characters. Trim or split longer texts before sending.
Secure the API key Use secret management (AWS Secrets Manager, GCP Secret Manager) instead of plain .env in production.
Monitor usage ElevenLabs provides usage stats in the dashboard; set alerts if you approach your quota.

🎉 Wrap‑Up

You now have a fully functional Python text‑to‑speech app powered by ElevenLabs. From a quick demo to a cloud‑hosted micro‑service or a custom voice clone, the API is flexible enough to fit most developer workflows.

Give it a spin, experiment with voice settings, and maybe even train a voice that sounds like you. The possibilities are only limited by your imagination (and the API quota).

Ready to bring natural speech to your next project? Try ElevenLabs today with the affiliate link: https://try.elevenlabs.io/kr07zfuqn1bp – you’ll get instant access to the API and a generous free tier to start building right away. Happy coding!

來源:DEV Community · dev.to