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

如何用 ElevenLabs 為 React App 加入語音功能

How to Add Voice to Your React App with ElevenLabs

AI 導讀

ElevenLabs 教學示範如何在 React App 中加入文字轉語音,透過 REST API 合成語音,並以自訂 React hook 管理載入狀態、錯誤和音訊播放。文章亦説明如何上載至少 30 秒的音訊樣本建立自訂語音,並介紹快取及串流等效能做法。

正文

Why Add Voice to a React App?

Voice is the next frontier of UI. Whether you’re building a language‑learning tool, an accessibility‑first dashboard, or a quirky chatbot, a natural‑sounding voice can make the experience feel human. Text‑to‑speech (TTS) services have come a long way, and today you can get studio‑grade quality with just a few lines of code.

One of the best options on the market right now is ElevenLabs – a modern TTS platform that offers ultra‑realistic speech, custom voice cloning, and a straightforward REST API. In this guide we’ll walk through adding ElevenLabs voice output to a React app, from getting an API key to playing back audio on the fly.

TL;DR – By the end of this article you’ll have a reusable useElevenLabs hook that turns any string into speech, and you’ll be ready to experiment with custom voices.


1. Grab an API Key

  1. Head over to the ElevenLabs sign‑up page: https://try.elevenlabs.io/kr07zfuqn1bp.
  2. Create an account (the free tier gives you 10 k characters per month – plenty for testing).
  3. In the dashboard, click API Keys → Create new key. Copy the key; you’ll need it in your React app.

Pro tip: Store the key in a .env file and never commit it to version control.

# .env
REACT_APP_ELEVENLABS_API_KEY=your_secret_key_here

2. Set Up a Fresh React Project

If you already have a project, skip to the next step. Otherwise:

npx create-react-app voice-demo
cd voice-demo
npm install axios

We’ll use axios for HTTP calls, but fetch works just as well.


3. Create a Tiny Service Wrapper

Create a new file src/api/elevenlabs.js:

// src/api/elevenlabs.js
import axios from "axios";

const BASE_URL = "https://api.elevenlabs.io/v1";

export const synthesizeSpeech = async ({
  text,
  voiceId = "EXAVITQu4vr4xnSDxMaL", // default “Rachel” voice
  stability = 0.75,
  similarityBoost = 0.75,
}) => {
  const apiKey = process.env.REACT_APP_ELEVENLABS_API_KEY;
  if (!apiKey) throw new Error("ElevenLabs API key not set");

  const response = await axios({
    method: "POST",
    url: `${BASE_URL}/text-to-speech/${voiceId}`,
    headers: {
      "xi-api-key": apiKey,
      "Content-Type": "application/json",
      Accept: "audio/mpeg",
    },
    data: {
      text,
      voice_settings: { stability, similarity_boost: similarityBoost },
    },
    responseType: "blob", // we want raw audio
  });

  return URL.createObjectURL(response.data);
};

What’s happening?

  • We POST the text to /text-to-speech/{voiceId}.
  • The voice_settings object lets you tweak the naturalness of the output.
  • The response is an MP3 blob; we turn it into an object URL so the browser can play it instantly.

4. Hook It Up with a Custom Hook

Now we’ll wrap the service in a React hook that handles loading state and errors.

// src/hooks/useElevenLabs.js
import { useState, useCallback } from "react";
import { synthesizeSpeech } from "../api/elevenlabs";

export const useElevenLabs = () => {
  const [audioUrl, setAudioUrl] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const speak = useCallback(
    async (text) => {
      setLoading(true);
      setError(null);
      try {
        const url = await synthesizeSpeech({ text });
        setAudioUrl(url);
      } catch (e) {
        console.error(e);
        setError(e);
      } finally {
        setLoading(false);
      }
    },
    []
  );

  const reset = () => {
    setAudioUrl(null);
    setError(null);
  };

  return { speak, audioUrl, loading, error, reset };
};

The hook returns:

  • speak(text): triggers synthesis.
  • audioUrl: a temporary URL you can feed to an <audio> element.
  • loading / error flags for UI feedback.

5. Build a Simple UI

Let’s create a component that lets users type a sentence and hear it back.

// src/components/VoiceBox.jsx
import { useState } from "react";
import { useElevenLabs } from "../hooks/useElevenLabs";

export const VoiceBox = () => {
  const [input, setInput] = useState("");
  const { speak, audioUrl, loading, error, reset } = useElevenLabs();

  const handleSpeak = async () => {
    if (!input.trim()) return;
    await speak(input);
  };

  return (
    <div style={{ maxWidth: 600, margin: "2rem auto", textAlign: "center" }}>
      <h2>🔊 Speak Anything</h2>
      <textarea
        rows={3}
        placeholder="Type something..."
        value={input}
        onChange={(e) => setInput(e.target.value)}
        style={{ width: "100%", padding: "0.5rem" }}
      />
      <br />
      <button onClick={handleSpeak} disabled={loading} style={{ marginTop: "1rem" }}>
        {loading ? "Generating…" : "Speak"}
      </button>
      {error && <p style={{ color: "red" }}>❗️ {error.message}</p>}
      {audioUrl && (
        <div style={{ marginTop: "1rem" }}>
          <audio src={audioUrl} controls autoPlay onEnded={reset} />
        </div>
      )}
    </div>
  );
};

Add the component to App.js:

import { VoiceBox } from "./components/VoiceBox";

function App() {
  return (
    <div className="App">
      <VoiceBox />
    </div>
  );
}

export default App;

Run npm start and you should be able to type text, click Speak, and hear a natural‑sounding voice in seconds.


6. Going Deeper: Voice Cloning

ElevenLabs also lets you create a custom voice from a short audio sample (as little as 30 seconds). The workflow is:

  1. Record a clean voice sample (WAV/MP3).
  2. Upload it via the /v1/voices/add endpoint.
  3. Use the returned voice_id in the synthesizeSpeech call.

A quick curl example:

curl -X POST "https://api.elevenlabs.io/v1/voices/add" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -F "name=MyCustomVoice" \
  -F "files=@/path/to/voice_sample.wav"

The response contains:

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

Plug that voice_id into our wrapper:

await synthesizeSpeech({ text: "Hello world!", voiceId: "abcd1234efgh5678ijkl" });

Now the app speaks your voice. This opens doors for personalized assistants, brand‑specific narrations, or even recreating historic figures (within legal bounds, of course).


7. Performance Tips

  • Cache the URL: The MP3 blob can be cached in localStorage keyed by the input text if you expect repeated phrases.
  • Streaming: ElevenLabs also offers a streaming endpoint (/text-to-speech/{voice_id}/stream). For real‑time chatbots you can pipe the stream into the Web Audio API.
  • Rate limits: The free tier caps at 10 k characters per month. Keep an eye on usage in the dashboard, and batch longer texts when possible.

8. Wrap‑Up

Adding voice to a React app is no longer a research‑paper exercise. With a few dozen lines of JavaScript and the powerful ElevenLabs API, you can transform static UI into an interactive, auditory experience. Whether you stick with the default voices or dive into custom cloning, the possibilities are limited only by your imagination.


Ready to give your app a voice?

Head over to ElevenLabs, grab your free API key, and start experimenting: https://try.elevenlabs.io/kr07zfuqn1bp. Happy coding, and may your apps be ever more talkative!


來源:DEV Community · dev.to