如何建立語音新聞閲讀器應用程式
Create a Voice-Powered News Reader App
這篇教學示範如何以 NewsAPI、ElevenLabs 和 Flask 建立語音新聞閲讀器,擷取指定主題的頭 5 則標題並轉成語音。Flask 會把 ElevenLabs 生成的 MP3 串流回瀏覽器,也可供手機應用程式嵌入播放。ElevenLabs 免費方案每月提供 10 k 個字元。
Why a Voice‑Powered News Reader?
If you’ve ever tried to skim headlines while commuting, cooking, or hitting the gym, you know the friction of reading on a small screen. A voice‑first news reader solves that problem by turning text into natural‑sounding speech that you can listen to hands‑free. In this post we’ll walk through building a simple Voice‑Powered News Reader using:
- A public news API (e.g., NewsAPI.org) to fetch the latest articles
- ElevenLabs for high‑quality text‑to‑speech (TTS) and voice cloning – see the affiliate link below for a free trial
- A lightweight Flask (Python) backend that stitches everything together
By the end you’ll have a small web service that returns an MP3 stream you can play in any browser or embed in a mobile app.
Architecture Overview
+----------------+ +-------------------+ +-------------------+
| Front‑end UI | <---> | Flask Backend | <---> | NewsAPI.org |
| (HTML/JS) | | /generate-audio | | (JSON) |
+----------------+ +-------------------+ +-------------------+
|
v
+-------------------+
| ElevenLabs TTS |
| (audio generation)|
+-------------------+
-
Client sends a request like
GET /generate-audio?topic=technology. - Flask fetches the top 5 headlines for the topic from NewsAPI.
- The concatenated article text is sent to ElevenLabs via their REST API.
- ElevenLabs returns an MP3 stream that Flask streams back to the client.
Prerequisites
| Item | Version |
|---|---|
| Python | 3.9+ |
| Flask | 2.3+ |
requests library |
latest |
| An API key for NewsAPI.org (free tier works) | – |
| An ElevenLabs API key (sign up through the affiliate link) | – |
# Create a virtual environment (optional but recommended)
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install flask requests
Step 1 – Pulling the Latest Headlines
First we need a function that talks to NewsAPI. The endpoint we’ll use is https://newsapi.org/v2/everything.
import requests
NEWSAPI_KEY = "YOUR_NEWSAPI_KEY"
def fetch_headlines(topic: str, limit: int = 5) -> str:
"""Return a plain‑text string containing the top `limit` headlines."""
url = "https://newsapi.org/v2/everything"
params = {
"q": topic,
"pageSize": limit,
"language": "en",
"sortBy": "publishedAt",
"apiKey": NEWSAPI_KEY,
}
resp = requests.get(url, params=params)
resp.raise_for_status()
articles = resp.json()["articles"]
# Build a simple script: "Headline 1. ... Headline 2. ..."
script = "\n".join([f"{i+1}. {a['title']}" for i, a in enumerate(articles)])
return script
Tip: If you want a richer experience, you can also pull the article description or full content (subject to the source’s licensing).
Step 2 – Turning Text into Speech with ElevenLabs
ElevenLabs offers a REST endpoint that accepts plain text and returns an audio file. The API is straightforward: POST https://api.elevenlabs.io/v1/text-to-speech/{voice_id}.
You’ll need a voice ID – the platform ships with a few default voices, or you can clone your own voice using their UI. For this tutorial we’ll use the default “Rachel” voice (voice_id = "21m00Tcm4TlvDq8ikWAM").
ELEVENLABS_API_KEY = "YOUR_ELEVENLABS_API_KEY"
VOICE_ID = "21m00Tcm4TlvDq8ikWAM" # Rachel (default)
def generate_audio(text: str) -> bytes:
"""Send `text` to ElevenLabs and receive MP3 bytes."""
url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}"
headers = {
"xi-api-key": ELEVENLABS_API_KEY,
"Content-Type": "application/json",
}
payload = {
"text": text,
"model_id": "eleven_monolingual_v1", # high‑quality model
"voice_settings": {
"stability": 0.75,
"similarity_boost": 0.85
}
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.content # MP3 binary
Why ElevenLabs? Their neural TTS sounds remarkably human, supports voice cloning, and the free tier gives you 10 k characters per month—perfect for a hobby project. Grab your API key through the affiliate link: https://try.elevenlabs.io/kr07zfuqn1bp
Step 3 – Glue It Together in Flask
Now we expose a single endpoint that accepts a topic query parameter, fetches headlines, generates audio, and streams the MP3 back to the caller.
from flask import Flask, request, Response, abort
app = Flask(__name__)
@app.route("/generate-audio")
def generate_audio_route():
topic = request.args.get("topic")
if not topic:
abort(400, description="Missing 'topic' query parameter")
# 1️⃣ Pull headlines
script = fetch_headlines(topic)
# 2️⃣ Convert to speech
try:
audio_bytes = generate_audio(script)
except requests.HTTPError as e:
abort(502, description=f"ElevenLabs error: {e}")
# 3️⃣ Stream MP3 back
return Response(
audio_bytes,
mimetype="audio/mpeg",
headers={"Content-Disposition": f'attachment; filename="{topic}.mp3"'}
)
if __name__ == "__main__":
app.run(debug=True)
Run the server:
python app.py
Visit http://127.0.0.1:5000/generate-audio?topic=technology in your browser. The download should start automatically, and playing the MP3 will read the top tech headlines in a natural voice.
Step 4 – Front‑End Quick Demo (Optional)
If you’d like a single‑page UI, a few lines of HTML + JavaScript can fetch and play the audio without a page reload.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Voice News Reader</title>
</head>
<body>
<h1>Voice‑Powered News Reader</h1>
<input id="topic" type="text" placeholder="Enter a topic (e.g., sports)" />
<button id="listen">Listen</button>
<audio id="player" controls></audio>
<script>
document.getElementById('listen').onclick = async () => {
const topic = document.getElementById('topic').value.trim();
if (!topic) return alert('Please type a topic');
const resp = await fetch(`/generate-audio?topic=${encodeURIComponent(topic)}`);
if (!resp.ok) return alert('Error: ' + resp.statusText);
const blob = await resp.blob();
const url = URL.createObjectURL(blob);
const player = document.getElementById('player');
player.src = url;
player.play();
};
</script>
</body>
</html>
Place this file in a templates folder, add a route in Flask to serve it, and you have a complete web app in under 100 lines of code.
Going Further
| Idea | How to Implement |
|---|---|
| Voice cloning – let users record a 30‑second sample and use ElevenLabs’ voice‑cloning endpoint to generate a personalized narrator. | |
Multiple languages – combine NewsAPI’s language param with ElevenLabs’ multilingual models. |
|
| Podcast style – stitch a short intro, headlines, and a closing line, then upload the MP3 to a storage bucket for on‑demand streaming. | |
| Mobile integration – expose the Flask endpoint via a simple Flask‑RESTful API and consume it from a React Native or Swift client. |
All of these extensions still rely on the same core building blocks we covered: fetch text, send it to ElevenLabs, and stream the audio.
Wrap‑Up & Call to Action
You now have a functional voice‑powered news reader that you can run locally, host on a cheap VPS, or embed in a larger product. The heavy lifting—producing clear, expressive speech—is handled by ElevenLabs, which consistently ranks among the best TTS services for developers. Their API is simple, their pricing (including a generous free tier) is friendly, and you can start right away with the affiliate link below.
🚀 Ready to give your app a human voice? Sign up at https://try.elevenlabs.io/kr07zfuqn1bp and get your API key in minutes. Happy coding!
來源:DEV Community · dev.to