Dev.to WebDev 🛠 Dev 👁 0 📖 6 min read

Create a Meditation App with AI-Generated Voice

Why a Meditation App Needs a Good Voice If you’ve ever tried a guided meditation on a cheap text‑to‑speech (TTS) engine, you know the difference a natural‑sounding voice makes. A soothing, human‑like voice can keep use

Why a Meditation App Needs a Good Voice

If you’ve ever tried a guided meditation on a cheap text‑to‑speech (TTS) engine, you know the difference a natural‑sounding voice makes. A soothing, human‑like voice can keep users relaxed, improve retention, and even boost the perceived value of your app. Luckily, modern AI voice platforms can generate high‑quality speech on the fly, letting you create endless meditation scripts without hiring a voice actor for every new session.

In this post we’ll walk through building a minimal meditation‑assistant that pulls a script from an API, sends it to an AI voice service, and streams the audio back to the user. We’ll use ElevenLabs as our TTS provider (you can sign up with the affiliate link below) and glue everything together with Python and a tiny Flask server. Feel free to swap the language or framework if you prefer JavaScript, Go, etc.

👉 Try ElevenLabs here: https://try.elevenlabs.io/kr07zfuqn1bp

What Makes ElevenLabs a Good Fit?

ElevenLabs offers:

  • Real‑time streaming – get audio back as it’s generated, perfect for meditation sessions that can be several minutes long.
  • Voice cloning – train a custom voice from a few minutes of audio if you want a brand‑specific narrator.
  • Simple REST API – works with curl, Python requests, or any HTTP client.

These features let you focus on the meditation logic rather than wrestling with low‑quality TTS.

Getting Your API Key

  1. Sign up through the affiliate link above.
  2. Once logged in, navigate to API → Keys and create a new key.
  3. Store the key securely – for this tutorial we’ll put it in an environment variable called ELEVENLABS_API_KEY.
export ELEVENLABS_API_KEY="your-secret-key-here"

A Quick Curl Test

Before writing code, verify that the API works with a simple curl request. Replace YOUR_VOICE_ID with the default “Rachel” voice (EXAVITQu4vr4xnG2X2eK) or any custom voice you’ve created.

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnG2X2eK" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "text": "Welcome to your meditation. Let’s begin by taking a deep breath.",
        "voice_settings": {
          "stability": 0.75,
          "similarity_boost": 0.85
        }
      }' \
  --output meditation.wav

If meditation.wav plays back cleanly, you’re ready to move to Python.

Building the Backend with Flask

Create a new folder, meditation-app, and install the dependencies:

mkdir meditation-app && cd meditation-app
python -m venv venv
source venv/bin/activate
pip install flask requests python-dotenv

Create a .env file with your API key:

ELEVENLABS_API_KEY=your-secret-key-here

app.py

import os
import uuid
from flask import Flask, request, send_file, jsonify
import requests
from dotenv import load_dotenv

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

app = Flask(__name__)

DEFAULT_VOICE = "EXAVITQu4vr4xnG2X2eK"  # Rachel

def generate_speech(text, voice_id=DEFAULT_VOICE):
    """Call ElevenLabs TTS and return the path to a temporary wav file."""
    endpoint = f"{BASE_URL}/text-to-speech/{voice_id}"
    payload = {
        "text": text,
        "voice_settings": {
            "stability": 0.75,
            "similarity_boost": 0.85
        }
    }
    headers = {
        "xi-api-key": API_KEY,
        "Content-Type": "application/json"
    }
    response = requests.post(endpoint, json=payload, headers=headers, stream=True)
    response.raise_for_status()

    tmp_path = f"/tmp/{uuid.uuid4()}.wav"
    with open(tmp_path, "wb") as f:
        for chunk in response.iter_content(chunk_size=8192):
            if chunk:
                f.write(chunk)
    return tmp_path

@app.route("/meditate", methods=["POST"])
def meditate():
    """
    Expected JSON:
    {
        "script": "Your meditation script here"
    }
    """
    data = request.get_json()
    if not data or "script" not in data:
        return jsonify({"error": "Missing 'script' field"}), 400

    wav_path = generate_speech(data["script"])
    return send_file(wav_path, mimetype="audio/wav", as_attachment=False)

if __name__ == "__main__":
    app.run(debug=True)

What’s happening?

  • The /meditate endpoint receives a raw meditation script.
  • generate_speech forwards the text to ElevenLabs, streams the result directly to a temporary file, and returns the file path.
  • Flask streams the WAV back to the client, which can be played in a web audio element or a mobile player.

Hooking Up a Tiny Front‑End

Create a static folder and add an index.html file:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Meditation Companion</title>
  <style>
    body { font-family: Arial, sans-serif; padding: 2rem; }
    textarea { width: 100%; height: 120px; }
    button { padding: 0.5rem 1rem; margin-top: 1rem; }
  </style>
</head>
<body>
  <h1>AI‑Guided Meditation</h1>
  <textarea id="script" placeholder="Enter your meditation script..."></textarea><br>
  <button id="play">Play</button>
  <audio id="player" controls></audio>

  <script>
    document.getElementById('play').onclick = async () => {
      const script = document.getElementById('script').value.trim();
      if (!script) return alert('Please enter a script');

      const resp = await fetch('/meditate', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({script})
      });

      if (!resp.ok) return alert('Error generating audio');

      const blob = await resp.blob();
      const url = URL.createObjectURL(blob);
      const player = document.getElementById('player');
      player.src = url;
      player.play();
    };
  </script>
</body>
</html>

Tell Flask to serve static files by adding the following line near the top of app.py:

app = Flask(__name__, static_folder="static")

Now run:

flask run

Open http://127.0.0.1:5000 in your browser, paste a meditation script (e.g., “Close your eyes, breathe in…”) and hit Play. The voice generated by ElevenLabs should guide you through the session.

Adding Background Music (Optional)

Meditation often benefits from soft ambient music. One approach is to fetch the speech audio, then mix it with a royalty‑free background track using pydub.

pip install pydub
from pydub import AudioSegment

def mix_with_music(speech_path, music_path, output_path, speech_gain=-3, music_gain=-12):
    speech = AudioSegment.from_wav(speech_path) + speech_gain
    music = AudioSegment.from_file(music_path).apply_gain(music_gain)

    # Loop music if it’s shorter than speech
    while len(music) < len(speech):
        music += music

    combined = speech.overlay(music[:len(speech)])
    combined.export(output_path, format="wav")
    return output_path

You could call mix_with_music inside generate_speech before returning the file. This keeps the API simple while giving your users a richer experience.

Scaling Thoughts

  • Serverless – Deploy the Flask endpoint as an AWS Lambda or Vercel serverless function. The request‑/response pattern works unchanged.
  • Caching – Store generated audio in a CDN (e.g., Cloudflare R2) keyed by a hash of the script. This reduces API calls and latency for popular meditations.
  • Voice Cloning – If you want a brand‑specific narrator, record ~5‑10 minutes of a calm speaker, upload it to ElevenLabs, and use the returned voice ID in generate_speech.

Wrap‑Up

You now have a working prototype that turns any text into a soothing meditation voice using ElevenLabs. The core ideas—sending text to a TTS API, streaming the result back, and optionally mixing background music—are reusable across many wellness, education, or accessibility projects.

Give it a spin, experiment with voice settings (stability, similarity_boost), and consider building a library of pre‑written scripts that users can select from. The sky’s the limit when AI‑generated voice meets mindfulness.

Ready to give your meditation app a professional, human‑like narrator?

Try ElevenLabs today: https://try.elevenlabs.io/kr07zfuqn1bp. Happy coding, and may your users find peace in every line of code!

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.