DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

Build an Audiobook Generator Using ElevenLabs API

Why an Audiobook Generator?

If you’ve ever tried to turn a long‑form article, a novel, or a collection of blog posts into an audio format, you know the pain of finding a natural‑sounding TTS engine, handling chunking, and stitching the pieces together. With modern voice AI, you can automate the whole pipeline and produce a polished audiobook in minutes. In this post we’ll walk through building a simple Audiobook Generator that pulls text from a file, sends it to the ElevenLabs API, and assembles the resulting audio files into a single MP3.

Tip: The ElevenLabs platform offers a free tier that’s generous enough for hobby projects and rapid prototyping. Grab your API key here: https://try.elevenlabs.io/kr07zfuqn1bp.


What You’ll Need

Item Reason
Python 3.8+ Easy HTTP client (requests) and audio handling (pydub).
An ElevenLabs API key To access the TTS endpoint.
A text source (plain‑text, markdown, or PDF) The content you want to narrate.
ffmpeg installed Required by pydub to manipulate audio files.

You can also replace Python with Node.js or plain curl if you prefer, but the example below sticks with Python for brevity.


Step 1: Grab Your ElevenLabs API Key

  1. Sign up (or log in) at the ElevenLabs developer portal: https://try.elevenlabs.io/kr07zfuqn1bp.
  2. Navigate to API Keys → Create new key.
  3. Copy the key; you’ll need it as an environment variable:
export ELEVENLABS_API_KEY="your_secret_key_here"
Enter fullscreen mode Exit fullscreen mode

Step 2: Install the Dependencies

pip install requests pydub tqdm
# On macOS/Linux you may need to install ffmpeg via brew/apt:
# brew install ffmpeg   # macOS
# sudo apt-get install ffmpeg   # Ubuntu
Enter fullscreen mode Exit fullscreen mode

Step 3: Chunk the Text

Audiobook‑style TTS works best when you feed the API reasonably sized chunks (≈ 2 000 characters). Too long and you risk hitting the request limit; too short and you waste time on extra HTTP calls.

import re

def chunk_text(text, max_len=2000):
    # Split on paragraph boundaries first
    paragraphs = text.split("\n\n")
    chunks = []
    current = ""

    for para in paragraphs:
        if len(current) + len(para) + 2 <= max_len:
            current += para + "\n\n"
        else:
            chunks.append(current.strip())
            current = para + "\n\n"

    if current:
        chunks.append(current.strip())
    return chunks
Enter fullscreen mode Exit fullscreen mode

Step 4: Call the ElevenLabs TTS Endpoint

Here’s a minimal wrapper that sends a chunk to ElevenLabs and returns the raw MP3 bytes.

import os
import requests
from tqdm import tqdm

ELEVEN_API_URL = "https://api.elevenlabs.io/v1/text-to-speech"
VOICE_ID = "EXAVITQu4vr4xnSDxMaL"   # default “Rachel” voice �� change as you like

def synthesize(chunk, output_path):
    headers = {
        "xi-api-key": os.getenv("ELEVENLABS_API_KEY"),
        "Content-Type": "application/json"
    }
    payload = {
        "text": chunk,
        "voice_settings": {
            "stability": 0.75,
            "similarity_boost": 0.75
        }
    }
    resp = requests.post(
        f"{ELEVEN_API_URL}/{VOICE_ID}",
        json=payload,
        headers=headers,
        stream=True
    )
    resp.raise_for_status()
    with open(output_path, "wb") as f:
        for data in resp.iter_content(chunk_size=8192):
            f.write(data)

def synthesize_all(chunks, out_dir="chunks"):
    os.makedirs(out_dir, exist_ok=True)
    for i, chunk in enumerate(tqdm(chunks, desc="Synthesizing")):
        out_file = os.path.join(out_dir, f"part_{i:04d}.mp3")
        synthesize(chunk, out_file)
Enter fullscreen mode Exit fullscreen mode

Note: The voice_settings parameters let you tweak the output’s stability and similarity boost. Experiment to find the sweet spot for your material.


Step 5: Stitch the Audio Together

Once each chunk is saved as an MP3, we can concatenate them using pydub.

from pydub import AudioSegment
import glob

def merge_chunks(chunk_dir="chunks", output_file="audiobook.mp3"):
    combined = AudioSegment.empty()
    for mp3_path in sorted(glob.glob(os.path.join(chunk_dir, "part_*.mp3"))):
        segment = AudioSegment.from_mp3(mp3_path)
        combined += segment
    combined.export(output_file, format="mp3")
    print(f"✅ Audiobook saved as {output_file}")
Enter fullscreen mode Exit fullscreen mode

Full Script in One Place

import os
import sys
from pathlib import Path

# ---- Configuration ----
TEXT_FILE = sys.argv[1] if len(sys.argv) > 1 else "book.txt"
OUTPUT_FILE = "my_audiobook.mp3"
# ------------------------

def main():
    # 1️⃣ Load the source text
    text = Path(TEXT_FILE).read_text(encoding="utf-8")

    # 2️⃣ Chunk it
    chunks = chunk_text(text)

    # 3️⃣ Generate audio for each chunk
    synthesize_all(chunks, out_dir="chunks")

    # 4️⃣ Merge into final MP3
    merge_chunks(chunk_dir="chunks", output_file=OUTPUT_FILE)

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Run it like:

python audiobook_generator.py my_novel.txt
Enter fullscreen mode Exit fullscreen mode

You’ll end up with a single my_audiobook.mp3 ready for upload to your favorite podcast host, Audible, or personal library.


Optional: Voice Cloning for a Custom Narrator

ElevenLabs also lets you clone a voice from a short (~30 s) recording. If you have a brand voice or want to sound like a favorite author, follow the steps in the dashboard to upload the sample and retrieve a new VOICE_ID. Swap the VOICE_ID constant in the script with the cloned ID, and you’re good to go.


Using Curl (If You Prefer a Quick Test)

Sometimes you just want to verify the endpoint works without writing code. Here’s a one‑liner that sends a short sentence and saves the MP3:

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnSDxMaL" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Hello, world! This is a quick test of the ElevenLabs API."}' \
--output hello.mp3
Enter fullscreen mode Exit fullscreen mode

Replace EXAVITQu4vr4xnSDxMaL with your custom voice ID if you’ve cloned one.


Deploying as a Small Web Service

If you want to expose the generator as an API (e.g., to let users upload their own texts), Flask or FastAPI are perfect companions. Below is a tiny FastAPI endpoint that accepts raw text and returns the generated MP3 stream:

from fastapi import FastAPI, HTTPException
from fastapi.responses import StreamingResponse
import io

app = FastAPI()

@app.post("/generate")
async def generate(text: str):
    chunks = chunk_text(text)
    # Store temporary audio in memory
    buffer = io.BytesIO()
    combined = AudioSegment.empty()
    for i, chunk in enumerate(chunks):
        # Re‑use the synthesize function but write to a BytesIO
        audio_bytes = requests.post(
            f"{ELEVEN_API_URL}/{VOICE_ID}",
            json={"text": chunk},
            headers={"xi-api-key": os.getenv("ELEVENLABS_API_KEY")},
        ).content
        combined += AudioSegment.from_mp3(io.BytesIO(audio_bytes))
    combined.export(buffer, format="mp3")
    buffer.seek(0)
    return StreamingResponse(buffer, media_type="audio/mpeg")
Enter fullscreen mode Exit fullscreen mode

Deploy to Render, Fly.io, or any container platform, and you have a fully functional audiobook‑as‑a‑service.


Wrapping Up

Building an audiobook generator is surprisingly straightforward when you have a high‑quality TTS engine at your fingertips. With just a few lines of Python and the power of ElevenLabs (https://try.elevenlabs.io/kr07zfuqn1bp), you can:

  • Turn any plain‑text source into a natural‑sounding narration.
  • Control voice stability and similarity to match the mood of your content.
  • Optionally clone a custom voice for brand‑specific audio.

All of this runs on modest hardware, and the free tier covers a decent amount of minutes per month—perfect for indie authors, educators, or anyone looking to add audio to their product.


🎧 Ready to give it a spin?

Grab your API key, clone the repo, and start turning words into sound. The ElevenLabs platform makes high‑fidelity voice synthesis accessible, so you can focus on the story, not the tech. Happy coding, and enjoy listening to the results! 🚀

Try ElevenLabs now: https://try.elevenlabs.io/kr07zfuqn1bp

Top comments (0)