DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

Create a Voice-Powered News Reader App

Why a Voice‑Powered News Reader?

Imagine you’re cooking, jogging, or just want to give your eyes a break. A quick “Hey, read me the headlines” and you’re instantly up‑to‑date. Building a voice‑driven news reader is a fun way to explore text‑to‑speech (TTS), voice cloning, and the APIs that make them tick. In this guide we’ll stitch together a simple Python backend that pulls the latest stories from a news API, sends the text to ElevenLabs for lifelike speech, and streams the audio to a minimal web UI.

Pro tip: ElevenLabs’ neural TTS is known for natural prosody and supports custom voice cloning, making it perfect for a personal news companion.


What You’ll Need

Component Reason
Python 3.9+ Core scripting language
Requests library Call external APIs (news, ElevenLabs)
FastAPI (or Flask) Tiny web server to serve audio files
HTML/JS Simple front‑end to trigger playback
ElevenLabs API key Convert text → high‑quality audio
NewsAPI.org (or any free news source) Source of headline text

All of these are free or have generous free tiers. Sign up for an ElevenLabs account using the affiliate link below to get your API key instantly:

👉 https://try.elevenlabs.io/kr07zfuqn1bp


1. Grab the Latest Headlines

We’ll use the free tier of NewsAPI.org. Sign up, grab a key, and store it in an environment variable called NEWS_API_KEY.

# news_fetcher.py
import os
import requests

NEWS_API_KEY = os.getenv("NEWS_API_KEY")
BASE_URL = "https://newsapi.org/v2/top-headlines"

def get_headlines(country="us", max_items=5):
    params = {
        "apiKey": NEWS_API_KEY,
        "country": country,
        "pageSize": max_items,
    }
    resp = requests.get(BASE_URL, params=params)
    resp.raise_for_status()
    data = resp.json()
    # Return a simple list of title strings
    return [article["title"] for article in data["articles"]]
Enter fullscreen mode Exit fullscreen mode

Running get_headlines() now gives you a list like:

[
  "NASA announces new moon mission",
  "Stock markets rally after earnings season",
  ...
]
Enter fullscreen mode Exit fullscreen mode

2. Turn Text into Speech with ElevenLabs

ElevenLabs offers a straightforward REST endpoint. The following curl example shows the raw request:

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAMPLE_VOICE_ID" \
  -H "xi‑api‑key: YOUR_ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "text": "Your headline goes here",
        "voice_settings": {
          "stability": 0.75,
          "similarity_boost": 0.85
        }
      }' \
  --output headline.mp3
Enter fullscreen mode Exit fullscreen mode

Replace EXAMPLE_VOICE_ID with the ID of a default voice (e.g., en_us_001). The response is an MP3 file you can play directly.

Python Wrapper

If you prefer staying in Python, here’s a tiny helper:

# tts.py
import os
import requests

ELEVEN_API_KEY = os.getenv("ELEVENLABS_API_KEY")
VOICE_ID = "en_us_001"  # default voice; you can clone your own later

def text_to_speech(text: str, output_path: str):
    url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}"
    payload = {
        "text": text,
        "voice_settings": {"stability": 0.75, "similarity_boost": 0.85},
    }
    headers = {
        "xi-api-key": ELEVEN_API_KEY,
        "Content-Type": "application/json",
    }
    resp = requests.post(url, json=payload, headers=headers)
    resp.raise_for_status()
    with open(output_path, "wb") as f:
        f.write(resp.content)
Enter fullscreen mode Exit fullscreen mode

Now you can generate an audio file for each headline:

from news_fetcher import get_headlines
from tts import text_to_speech

headlines = get_headlines()
for i, title in enumerate(headlines):
    text_to_speech(title, f"audio_{i}.mp3")
Enter fullscreen mode Exit fullscreen mode

3. Voice Cloning (Optional but Cool)

ElevenLabs lets you upload a short voice sample (≈30 seconds) and receive a custom VOICE_ID. This is handy if you want the news read in your voice.

  1. Record a WAV/MP3 of yourself speaking naturally.
  2. Use the Create Voice endpoint:
curl -X POST "https://api.elevenlabs.io/v1/voices/add" \
  -H "xi-api-key: YOUR_ELEVENLABS_API_KEY" \
  -F "name=MyVoice" \
  -F "files=@/path/to/voice_sample.wav"
Enter fullscreen mode Exit fullscreen mode

The response contains a voice_id. Swap VOICE_ID in tts.py with that ID, and every article will now sound like you.


4. Serve the Audio via FastAPI

A lightweight API makes the front‑end feel snappy. We’ll bundle the headline fetch and TTS into a single endpoint that returns the MP3 data.

# server.py
import os
import uuid
from fastapi import FastAPI, Response
from news_fetcher import get_headlines
from tts import text_to_speech

app = FastAPI()
TMP_DIR = "./tmp"
os.makedirs(TMP_DIR, exist_ok=True)

@app.get("/news-audio")
def news_audio():
    headlines = get_headlines()
    # Concatenate all headlines into one paragraph
    full_text = ". ".join(headlines) + "."
    filename = f"{TMP_DIR}/{uuid.uuid4()}.mp3"
    text_to_speech(full_text, filename)
    with open(filename, "rb") as f:
        audio_bytes = f.read()
    # Clean up the temp file
    os.remove(filename)
    return Response(content=audio_bytes, media_type="audio/mpeg")
Enter fullscreen mode Exit fullscreen mode

Run it with:

uvicorn server:app --reload
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:8000/news-audio and you’ll hear the latest headlines spoken back to you.


5. Minimal Front‑End

A single HTML file can trigger the audio fetch and play it automatically.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Voice News Reader</title>
</head>
<body>
  <h1>🗞️ Voice‑Powered News</h1>
  <button id="readBtn">Read Latest Headlines</button>
  <audio id="player" controls></audio>

  <script>
    const btn = document.getElementById('readBtn');
    const player = document.getElementById('player');

    btn.onclick = async () => {
      btn.disabled = true;
      btn.textContent = 'Fetching…';
      const resp = await fetch('http://localhost:8000/news-audio');
      const blob = await resp.blob();
      player.src = URL.createObjectURL(blob);
      player.play();
      btn.textContent = 'Read Again';
      btn.disabled = false;
    };
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Open the file in a browser, click Read Latest Headlines, and you’ll hear the news narrated by ElevenLabs’ high‑fidelity voice.


6. Polishing the Experience

  • Cache audio: Store the generated MP3 for a few minutes to avoid repeated TTS calls (they count against your quota).
  • Add a language selector: Pass a language param to NewsAPI and switch the ElevenLabs voice accordingly.
  • Error handling: Gracefully handle network hiccups and display fallback text.

7. Going Further

  • Push notifications: Combine with a service worker to alert users when a new audio version is ready.
  • Voice commands: Use the Web Speech API to let users say “Read me the tech news” and filter categories on the fly.
  • Multi‑speaker podcasts: Clone multiple voices (e.g., one for sports, another for finance) to give each section a distinct personality.

Wrap‑Up & Call to Action

You now have a fully functional voice‑powered news reader that pulls fresh headlines, transforms them into natural‑sounding speech, and streams the result to any browser. The heavy lifting is done by ElevenLabs, whose neural TTS and voice cloning capabilities bring a human‑like feel to your app.

Ready to give your users (or yourself) a hands‑free news experience? Grab your ElevenLabs API key via the affiliate link below, spin up the code, and start experimenting with custom voices.

🚀 Try ElevenLabs today and make your news reader sound amazing: https://try.elevenlabs.io/kr07zfuqn1bp

Top comments (0)