JavaScript SDK

Scribe: transkrypcja mowy na tekst w czasie rzeczywistym w JavaScript

Przegląd Scribe i jego możliwości znajdziesz w omówieniu funkcji Speech to Text . Przewodniki krok po kroku znajdziesz w sekcji streaming po stronie klienta.

Instalacja

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

Użyj umiejętności ElevenLabs Speech to Text, aby transkrybować audio z pomocą asystenta AI do programowania:

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

Z tej biblioteki możesz korzystać w każdym projekcie opartym na JavaScript. Jeśli używasz React, rozważ użycie hooka useScribe, który zapewnia wbudowane zarządzanie stanem i obsługę cyklu życia.

Użycie

Oto minimalny działający przykład, który łączy się z Scribe i zapisuje wyniki transkrypcji w logach:

import { Scribe, RealtimeEvents } from "@elevenlabs/client";
const token = await fetchTokenFromServer();
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
microphone: {
echoCancellation: true,
noiseSuppression: true,
},
});
connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) => {
console.log("Partial:", data.text);
});
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) => {
console.log("Committed:", data.text);
});
// Later, close the connection
connection.close();

Uzyskiwanie tokenu

Scribe wymaga tokenu jednorazowego do uwierzytelniania. Utwórz endpoint API na swoim serwerze:

// 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 });
});

Twój klucz API ElevenLabs jest poufny. Nigdy nie udostępniaj go klientowi. Zawsze generuj token na serwerze.

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

Opcje połączenia

Scribe.connect() przyjmuje opcje mikrofonu albo ręczne opcje audio. Oba warianty mają wspólny zestaw opcji podstawowych.

Opcje podstawowe

WłaściwośćTypDomyślnieOpis
tokenstringToken jednorazowy do uwierzytelniania WebSocket.
modelIdstringIdentyfikator modelu (np. "scribe_v2_realtime").
baseUristring"wss://api.elevenlabs.io"Własny bazowy URI WebSocket.
commitStrategyCommitStrategy"manual""manual" lub "vad".
vadSilenceThresholdSecsnumber1.5Liczba sekund ciszy przed zatwierdzeniem przez VAD (0.3–3.0).
vadThresholdnumber0.4Czułość VAD (0.1–0.9, niższa wartość oznacza większą czułość).
minSpeechDurationMsnumber100Minimalny czas mowy w ms (50–2000).
minSilenceDurationMsnumber100Minimalny czas ciszy w ms (50–2000).
languageCodestringKod języka ISO-639-1 lub ISO-639-3. Zostaw puste, aby wykrywać automatycznie.
includeTimestampsbooleanfalseOtrzymuj znaczniki czasu na poziomie słów przez zdarzenie COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS.

Opcje mikrofonu

Przekaż obiekt microphone, aby przesyłać audio bezpośrednio z mikrofonu użytkownika. Połączenie automatycznie obsługuje getUserMedia i kodowanie audio.

const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
microphone: {
deviceId: "optional-device-id",
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
});
WłaściwośćTypOpis
deviceIdstringIdentyfikator konkretnego mikrofonu.
echoCancellationbooleanWłącza eliminację echa.
noiseSuppressionbooleanWłącza redukcję szumów.
autoGainControlbooleanWłącza automatyczną regulację wzmocnienia.

Ręczne opcje audio

Przekaż audioFormat i sampleRate, aby ręcznie wysyłać dane audio przez connection.send().

import { AudioFormat } from "@elevenlabs/client";
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
});
WłaściwośćTypOpis
audioFormatAudioFormatFormat kodowania audio (np. AudioFormat.PCM_16000).
sampleRatenumberCzęstotliwość próbkowania w Hz. Musi pasować do audioFormat.

Enum AudioFormat

enum AudioFormat {
PCM_8000 = "pcm_8000",
PCM_16000 = "pcm_16000",
PCM_22050 = "pcm_22050",
PCM_24000 = "pcm_24000",
PCM_44100 = "pcm_44100",
PCM_48000 = "pcm_48000",
ULAW_8000 = "ulaw_8000",
}

Tryb mikrofonu

Przesyłaj audio bezpośrednio z mikrofonu użytkownika:

import { Scribe, RealtimeEvents } from "@elevenlabs/client";
async function transcribeFromMicrophone() {
const token = await fetchToken();
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
microphone: {
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
});
connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) => {
document.getElementById("live").textContent = data.text;
});
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) => {
const el = document.createElement("p");
el.textContent = data.text;
document.getElementById("transcripts").appendChild(el);
document.getElementById("live").textContent = "";
});
document.getElementById("stop").addEventListener("click", () => {
connection.close();
});
}

Ręczny tryb audio (transkrypcja pliku)

Transkrybuj nagrane wcześniej pliki audio, ręcznie wysyłając dane audio:

import { Scribe, RealtimeEvents, AudioFormat } from "@elevenlabs/client";
async function transcribeFile(file) {
const token = await fetchToken();
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
});
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) => {
console.log("Transcript:", data.text);
});
// 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));
connection.send({ audioBase64: base64 });
await new Promise((resolve) => setTimeout(resolve, 50));
}
// Commit and close
connection.commit();
}

RealtimeConnection

Scribe.connect() zwraca instancję RealtimeConnection z poniższymi metodami.

on(event, listener)

Zarejestruj nasłuchiwanie zdarzenia. Dostępne typy zdarzeń znajdziesz w sekcji Zdarzenia.

connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) => {
console.log("Committed:", data.text);
});

off(event, listener)

Usuń wcześniej zarejestrowane nasłuchiwanie zdarzenia.

const handler = (data) => console.log(data.text);
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, handler);
// Later
connection.off(RealtimeEvents.COMMITTED_TRANSCRIPT, handler);

send(data)

Wyślij dane audio do Scribe (tylko w ręcznym trybie audio).

connection.send({
audioBase64: base64AudioChunk,
commit: false, // Optional: commit immediately
sampleRate: 16000, // Optional: override sample rate
previousText: "Previous transcription text", // Optional: context from a previous transcription
});

Pole previousText można wysłać tylko w pierwszym fragmencie audio sesji. Wysłanie go w kolejnych fragmentach powoduje błąd.

commit()

Ręcznie zatwierdź bieżącą transkrypcję. Jest to potrzebne tylko przy użyciu CommitStrategy.MANUAL.

connection.commit();

close()

Zamknij połączenie WebSocket i zwolnij zasoby (strumień mikrofonu, kontekst audio).

connection.close();

Zdarzenia

Rejestruj nasłuchiwanie zdarzeń przez connection.on(event, listener). Wszystkie zdarzenia są dostępne jako stałe w enumie RealtimeEvents.

Zdarzenia transkrypcji

ZdarzenieDaneOpis
SESSION_STARTED{ session_id: string }Sesja Scribe rozpoczęta.
PARTIAL_TRANSCRIPT{ text: string }Tymczasowy wynik transkrypcji.
COMMITTED_TRANSCRIPT{ text: string }Sfinalizowany wynik transkrypcji.
COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS{ text: string; language_code?: string; words?: WordsItem[] }Sfinalizowany wynik z czasem na poziomie słów.

Typ WordsItem zawiera informacje o czasie na poziomie słów:

interface WordsItem {
text?: string; // Word text
start?: number; // Start time in seconds
end?: number; // End time in seconds
type?: "word" | "spacing"; // Token type
speaker_id?: string; // Speaker identifier
}

Zdarzenia połączenia

ZdarzenieDaneOpis
OPENEventPołączenie WebSocket otwarte.
CLOSEEventPołączenie WebSocket zamknięte.
ERRORError | EventOgólny błąd.

Zdarzenia błędów

Wszystkie zdarzenia błędów otrzymują { error: string }.

ZdarzenieOpis
AUTH_ERRORBłąd uwierzytelniania.
QUOTA_EXCEEDEDPrzekroczono limit użycia.
COMMIT_THROTTLEDŻądanie zatwierdzenia zostało ograniczone.
TRANSCRIBER_ERRORBłąd silnika transkrypcji.
UNACCEPTED_TERMSWarunki korzystania z usługi nie zostały zaakceptowane.
RATE_LIMITEDOsiągnięto limit żądań.
INPUT_ERRORNieprawidłowy format danych wejściowych.
QUEUE_OVERFLOWKolejka przetwarzania jest pełna.
RESOURCE_EXHAUSTEDZasoby serwera są wyczerpane.
SESSION_TIME_LIMIT_EXCEEDEDOsiągnięto maksymalny czas sesji.
CHUNK_SIZE_EXCEEDEDFragment audio jest za duży.
INSUFFICIENT_AUDIO_ACTIVITYZa mało aktywności audio, aby utrzymać połączenie.

Strategie zatwierdzania

Określ, kiedy transkrypcje są zatwierdzane:

import { Scribe, CommitStrategy } from '@elevenlabs/client';
// Manual (default): you control when to commit
const connection = Scribe.connect({
token,
modelId: 'scribe_v2_realtime',
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
commitStrategy: CommitStrategy.MANUAL,
});
// Send audio, then commit when ready
connection.send({ audioBase64: chunk });
connection.commit();
// Voice Activity Detection: Scribe detects silences and commits automatically
const connection = Scribe.connect({
token,
modelId: 'scribe_v2_realtime',
microphone: { echoCancellation: true },
commitStrategy: CommitStrategy.VAD,
});

Więcej informacji znajdziesz w sekcji Transkrypcje i strategie zatwierdzania.

Pełny przykład

Oto pełny przykład, który transkrybuje audio z mikrofonu przy użyciu strategii zatwierdzania opartej na VAD:

import { Scribe, RealtimeEvents, CommitStrategy } from "@elevenlabs/client";
async function startTranscription() {
const token = await fetchToken();
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
commitStrategy: CommitStrategy.VAD,
microphone: {
echoCancellation: true,
noiseSuppression: true,
},
});
connection.on(RealtimeEvents.SESSION_STARTED, (data) => {
console.log("Session started:", data.session_id);
});
connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) => {
document.getElementById("live").textContent = data.text;
});
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) => {
const el = document.createElement("p");
el.textContent = data.text;
document.getElementById("transcripts").appendChild(el);
document.getElementById("live").textContent = "";
});
connection.on(RealtimeEvents.ERROR, (error) => {
console.error("Scribe error:", error);
});
// Stop button
document.getElementById("stop").addEventListener("click", () => {
connection.close();
});
}
document.getElementById("start").addEventListener("click", startTranscription);