Hoppa till navigering

React SDK

useScribe: tal-till-text-transkribering i realtid i React

För en översikt över Scribe och dess funktioner, se översikten över Speech to Text . För stegvisa användarguider, se streaming på klientsidan.

Installation

npm install @elevenlabs/react
# or
yarn add @elevenlabs/react
# or
pnpm install @elevenlabs/react

Använd ElevenLabs Speech to Text-skill för att transkribera ljud från din AI-kodassistent:

npx skills add elevenlabs/skills --skill speech-to-text

@elevenlabs/react återexporterar allt från @elevenlabs/client, så du behöver inte installera båda paketen.

Användning

Här är ett minimalt fungerande exempel som ansluter till Scribe och visar transkribering i realtid:

import { useScribe } from "@elevenlabs/react";
import { useEffect } from "react";
function MyComponent() {
const scribe = useScribe({
modelId: "scribe_v2_realtime",
onPartialTranscript: (data) => {
console.log("Partial:", data.text);
},
onCommittedTranscript: (data) => {
console.log("Committed:", data.text);
},
});
// Start recording
const handleStart = async () => {
try {
const token = await fetchTokenFromServer();
await scribe.connect({
token,
microphone: {
echoCancellation: true,
noiseSuppression: true,
},
});
} catch (err) {
console.error("Failed to start recording:", err);
}
};
// Stop recording
const handleDisconnect = () => {
scribe.disconnect();
};
// Disconnect on unmount
useEffect(() => {
return () => {
if (scribe.isConnected) {
scribe.disconnect();
}
};
}, [scribe]);
return (
<div>
<button onClick={handleStart} disabled={scribe.isConnected}>
Start Recording
</button>
<button onClick={handleDisconnect} disabled={!scribe.isConnected}>
Stop
</button>
{scribe.partialTranscript && <p>Live: {scribe.partialTranscript}</p>}
<div>
{scribe.committedTranscripts.map((t) => (
<p key={t.id}>{t.text}</p>
))}
</div>
</div>
);
}

Hämta en token

Scribe kräver en engångstoken för autentisering. Skapa en API-slutpunkt på din server:

// Node.js server
app.get("/scribe-token", yourAuthMiddleware, async (req, res) => {
const response = await fetch("https://api.elevenlabs.io/v1/single-use-token/realtime_scribe", {
method: "POST",
headers: {
"xi-api-key": process.env.ELEVENLABS_API_KEY,
},
});
const data = await response.json();
res.json({ token: data.token });
});

Din ElevenLabs API-nyckel är känslig. Exponera den aldrig för klienten. Generera alltid token på servern.

// Client
const fetchToken = async () => {
const response = await fetch("/scribe-token");
const { token } = await response.json();
return token;
};

Hook-alternativ

Konfigurera hooken med standardalternativ och callbacks:

const scribe = useScribe({
// Connection options (can be overridden in connect())
token: "optional-default-token",
modelId: "scribe_v2_realtime",
baseUri: "wss://api.elevenlabs.io",
// VAD options
commitStrategy: CommitStrategy.VAD,
vadSilenceThresholdSecs: 0.5,
vadThreshold: 0.5,
minSpeechDurationMs: 100,
minSilenceDurationMs: 500,
languageCode: "en",
// Microphone options (for automatic mode)
microphone: {
deviceId: "optional-device-id",
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
// Manual audio options (for file transcription)
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
// Auto-connect on mount
autoConnect: false,
// Event callbacks
onSessionStarted: () => console.log("Session started"),
onPartialTranscript: (data) => console.log("Partial:", data.text),
onCommittedTranscript: (data) => console.log("Committed:", data.text),
onCommittedTranscriptWithTimestamps: (data) => console.log("With timestamps:", data),
onError: (error) => console.error("Error:", error),
onAuthError: (data) => console.error("Auth error:", data.error),
onQuotaExceededError: (data) => console.error("Quota exceeded:", data.error),
onConnect: () => console.log("Connected"),
onDisconnect: () => console.log("Disconnected"),
});

Anslutningsalternativ

EgenskapTypBeskrivning
tokenstringEngångstoken för WebSocket-autentisering.
modelIdstringModell-ID (t.ex. "scribe_v2_realtime").
baseUristringAnpassad bas-URI för WebSocket. Standard är wss://api.elevenlabs.io.

VAD-alternativ

Dessa alternativ styr när transkriberingar automatiskt bekräftas när du använder bekräftelsestrategin VAD.

EgenskapTypStandardBeskrivning
commitStrategyCommitStrategy"manual""manual" eller "vad".
vadSilenceThresholdSecsnumber1.5Sekunders tystnad innan VAD bekräftar (0.3–3.0).
vadThresholdnumber0.4VAD-känslighet (0.1–0.9, lägre är känsligare).
minSpeechDurationMsnumber100Kortaste talduration i ms (50–2000).
minSilenceDurationMsnumber100Kortaste tystnadsduration i ms (50–2000).

Ljudalternativ

EgenskapTypBeskrivning
languageCodestringSpråkkod enligt ISO-639-1 eller ISO-639-3. Lämna tomt för automatisk identifiering.
microphoneobjectMikrofoninställningar för mikrofonläget. Se nedan.
audioFormatAudioFormatLjudkodningsformat för manuellt läge (t.ex. AudioFormat.PCM_16000).
sampleRatenumberSamplingsfrekvens för manuellt läge. Måste matcha audioFormat.

Objektet microphone accepterar:

EgenskapTypBeskrivning
deviceIdstringID för en specifik mikrofonenhet.
echoCancellationbooleanAktivera ekosläckning.
noiseSuppressionbooleanAktivera brusreducering.
autoGainControlbooleanAktivera automatisk nivåkontroll.

Beteendealternativ

EgenskapTypStandardBeskrivning
autoConnectbooleanfalseAnslut automatiskt när komponenten monteras.
includeTimestampsbooleanfalseTa emot tidsstämplar på ordnivå. Aktiveras automatiskt när onCommittedTranscriptWithTimestamps anges.

Callbacks

Alla händelse-callbacks är valfria och kan anges som hook-alternativ:

  • onConnect – hanterare som anropas när WebSocket-anslutningen har upprättats.
  • onDisconnect – hanterare som anropas när WebSocket-anslutningen stängs.
  • onSessionStarted – hanterare som anropas när Scribe-sessionen startar.
  • onPartialTranscript – hanterare som anropas med preliminära transkriberingsresultat. Tar emot { text: string }.
  • onCommittedTranscript – hanterare som anropas med slutförda transkriberingsresultat. Tar emot { text: string }.
  • onCommittedTranscriptWithTimestamps – hanterare som anropas med slutförda transkriberingsresultat inklusive tid på ordnivå. Tar emot { text: string; words?: { start: number; end: number }[] }.
  • onError – generell felhanterare för alla fel. Tar emot Error | Event.
  • onAuthError – hanterare som anropas vid autentiseringsfel. Tar emot { error: string }.

Fel-callbacks

Den generella callbacken onError utlöses vid alla fel. Det finns även specifika fel-callbacks för mer detaljerad hantering. Alla specifika fel-callbacks tar emot { error: string }.

CallbackBeskrivning
onErrorGenerell felhanterare för alla fel.
onAuthErrorAutentiseringsfel.
onQuotaExceededErrorAnvändningskvoten har överskridits.
onCommitThrottledErrorBekräftelsebegäran begränsades.
onTranscriberErrorFel i transkriberingsmotorn.
onUnacceptedTermsErrorAnvändarvillkoren har inte godkänts.
onRateLimitedErrorHastighetsbegränsad.
onInputErrorOgiltigt inmatningsformat.
onQueueOverflowErrorBearbetningskön är full.
onResourceExhaustedErrorServerresurserna har nått kapacitet.
onSessionTimeLimitExceededErrorMaximal sessionstid har uppnåtts.
onChunkSizeExceededErrorLjudsegmentet är för stort.
onInsufficientAudioActivityErrorInte tillräcklig ljudaktivitet för att behålla anslutningen.

Mikrofonläge

Streama ljud direkt från användarens mikrofon:

function MicrophoneTranscription() {
const scribe = useScribe({
modelId: "scribe_v2_realtime",
});
const startRecording = async () => {
const token = await fetchToken();
await scribe.connect({
token,
microphone: {
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
});
};
return (
<div>
<button onClick={startRecording} disabled={scribe.isConnected}>
{scribe.status === "connecting" ? "Connecting..." : "Start"}
</button>
<button onClick={scribe.disconnect} disabled={!scribe.isConnected}>
Stop
</button>
{scribe.partialTranscript && (
<div>
<strong>Speaking:</strong> {scribe.partialTranscript}
</div>
)}
{scribe.committedTranscripts.map((transcript) => (
<div key={transcript.id}>{transcript.text}</div>
))}
</div>
);
}

Manuellt ljudläge (filtranskribering)

Transkribera förinspelade ljudfiler:

import { useScribe, AudioFormat } from "@elevenlabs/react";
import { useState } from "react";
function FileTranscription() {
const [file, setFile] = useState<File | null>(null);
const scribe = useScribe({
modelId: "scribe_v2_realtime",
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
});
const transcribeFile = async () => {
if (!file) return;
const token = await fetchToken();
await scribe.connect({ token });
// Decode audio file
const arrayBuffer = await file.arrayBuffer();
const audioContext = new AudioContext({ sampleRate: 16000 });
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
// Convert to PCM16
const channelData = audioBuffer.getChannelData(0);
const pcmData = new Int16Array(channelData.length);
for (let i = 0; i < channelData.length; i++) {
const sample = Math.max(-1, Math.min(1, channelData[i]));
pcmData[i] = sample < 0 ? sample * 32768 : sample * 32767;
}
// Send in chunks
const chunkSize = 4096;
for (let offset = 0; offset < pcmData.length; offset += chunkSize) {
const chunk = pcmData.slice(offset, offset + chunkSize);
const bytes = new Uint8Array(chunk.buffer);
const base64 = btoa(String.fromCharCode(...bytes));
scribe.sendAudio(base64);
await new Promise((resolve) => setTimeout(resolve, 50));
}
// Commit transcription
scribe.commit();
};
return (
<div>
<input type="file" accept="audio/*" onChange={(e) => setFile(e.target.files?.[0] || null)} />
<button onClick={transcribeFile} disabled={!file || scribe.isConnected}>
Transcribe
</button>
{scribe.committedTranscripts.map((transcript) => (
<div key={transcript.id}>{transcript.text}</div>
))}
</div>
);
}

Returvärden

Tillstånd

  • status – aktuell anslutningsstatus: "disconnected", "connecting", "connected", "transcribing" eller "error".
  • isConnected – booleskt värde som anger om anslutning finns.
  • isTranscribing – booleskt värde som anger om transkribering pågår aktivt.
  • partialTranscript – aktuell partiell (preliminär) transkriberingssträng.
  • committedTranscripts – matris med TranscriptSegment-objekt (se nedan).
  • error – aktuellt felmeddelande eller null.
const scribe = useScribe(/* options */);
console.log(scribe.status); // "connected"
console.log(scribe.isConnected); // true
console.log(scribe.partialTranscript); // "hello world"
console.log(scribe.committedTranscripts); // [{ id: "...", text: "...", words: ..., isFinal: true }]
console.log(scribe.error); // null or error string

Varje bekräftat transkriberingssegment har följande struktur:

interface TranscriptSegment {
id: string; // Unique identifier
text: string; // Transcript text
timestamp: number; // Unix timestamp
isFinal: boolean; // Always true for committed transcripts
}

Metoder

connect(options?)

Anslut till Scribe. Alternativ som anges här åsidosätter hookens standardvärden:

await scribe.connect({
token: "your-token", // Required
microphone: {
/* ... */
}, // For microphone mode
// OR
audioFormat: AudioFormat.PCM_16000, // For manual mode
sampleRate: 16000,
});

disconnect()

Koppla från och frigör resurser:

scribe.disconnect();

sendAudio(audioBase64, options?)

Skicka ljuddata (endast manuellt läge):

scribe.sendAudio(base64AudioChunk, {
commit: false, // Optional: commit immediately
sampleRate: 16000, // Optional: override sample rate
previousText: "Previous transcription text", // Optional: context from a previous transcription. Can only be sent in the first audio chunk.
});

Fältet previousText kan bara skickas i sessionens första ljudsegment. Om det skickas i efterföljande segment uppstår ett fel.

commit()

Bekräfta den aktuella transkriberingen manuellt:

scribe.commit();

clearTranscripts()

Rensa alla transkriberingar från tillståndet:

scribe.clearTranscripts();

getConnection()

Hämta den underliggande anslutningsinstansen:

const connection = scribe.getConnection();
// Returns RealtimeConnection | null

Bekräftelsestrategier

Styr när transkriberingar bekräftas:

import { CommitStrategy } from '@elevenlabs/react';
// Manual (default) - you control when to commit
const scribe = useScribe({
commitStrategy: CommitStrategy.MANUAL,
});
// Later...
scribe.commit(); // Commit transcription
// Voice Activity Detection - model detects silences and automatically commits
const scribe = useScribe({
commitStrategy: CommitStrategy.VAD,
});

Mer information finns i Transkriberingar och bekräftelsestrategier.

Komplett exempel

Här är ett komplett exempel på en React-komponent som använder hooken useScribe med VAD-baserad bekräftelsestrategi:

import { useScribe, CommitStrategy } from "@elevenlabs/react";
import { useEffect } from "react";
function ScribeDemo() {
const scribe = useScribe({
modelId: "scribe_v2_realtime",
commitStrategy: CommitStrategy.VAD,
onSessionStarted: () => console.log("Started"),
onCommittedTranscript: (data) => console.log("Committed:", data.text),
onError: (error) => console.error("Error:", error),
});
const startMicrophone = async () => {
const token = await fetchToken();
await scribe.connect({
token,
microphone: {
echoCancellation: true,
noiseSuppression: true,
},
});
};
const handleDisconnect = () => scribe.disconnect();
const handleClearTranscripts = () => scribe.clearTranscripts();
useEffect(() => {
return () => {
handleDisconnect();
};
}, []);
return (
<div>
<h1>Scribe Demo</h1>
{/* Status */}
<div>
Status: {scribe.status}
{scribe.error && <span>Error: {scribe.error}</span>}
</div>
{/* Controls */}
<div>
{!scribe.isConnected ? (
<button onClick={startMicrophone}>Start Recording</button>
) : (
<button onClick={handleDisconnect}>Stop</button>
)}
<button onClick={handleClearTranscripts}>Clear</button>
</div>
{/* Live Transcript */}
{scribe.partialTranscript && (
<div>
<strong>Live:</strong> {scribe.partialTranscript}
</div>
)}
{/* Committed Transcripts */}
<div>
<h2>Transcripts ({scribe.committedTranscripts.length})</h2>
{scribe.committedTranscripts.map((t) => (
<div key={t.id}>
<span>{new Date(t.timestamp).toLocaleTimeString()}</span>
<p>{t.text}</p>
</div>
))}
</div>
</div>
);
}