SDK JavaScript

Scribe : transcription parole-texte en temps réel avec JavaScript

Pour une présentation de Scribe et de ses capacités, consultez la présentation de Speech to Text . Pour des guides d’utilisation étape par étape, consultez le streaming côté client.

Installation

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

Utilisez la compétence Speech to Text d’ElevenLabs pour transcrire de l’audio depuis votre assistant de programmation IA :

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

Cette bibliothèque peut être utilisée dans tout projet basé sur JavaScript. Si vous utilisez React, envisagez le hook useScribe, qui fournit une gestion intégrée de l’état et du cycle de vie.

Utilisation

Voici un exemple minimal fonctionnel qui se connecte à Scribe et affiche les résultats de transcription :

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();

Obtenir un jeton

Scribe nécessite un jeton à usage unique pour l’authentification. Créez un point de terminaison API sur votre serveur :

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

Votre clé API ElevenLabs est sensible. Ne l’exposez jamais au client. Générez toujours le jeton sur le serveur.

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

Options de connexion

Scribe.connect() accepte des options de microphone ou des options audio manuelles. Les deux partagent un ensemble commun d’options de base.

Options de base

PropriétéTypeValeur par défautDescription
tokenstringJeton à usage unique pour l’authentification WebSocket.
modelIdstringID du modèle (par exemple, "scribe_v2_realtime").
baseUristring"wss://api.elevenlabs.io"URI de base WebSocket personnalisée.
commitStrategyCommitStrategy"manual""manual" ou "vad".
vadSilenceThresholdSecsnumber1.5Secondes de silence avant validation par VAD (0.3-3.0).
vadThresholdnumber0.4Sensibilité du VAD (0.1-0.9, plus basse signifie plus sensible).
minSpeechDurationMsnumber100Durée minimale de parole en ms (50-2000).
minSilenceDurationMsnumber100Durée minimale de silence en ms (50-2000).
languageCodestringCode de langue ISO-639-1 ou ISO-639-3. Laissez vide pour la détection automatique.
includeTimestampsbooleanfalseRecevez les horodatages au niveau des mots via l’événement COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS.

Options de microphone

Transmettez un objet microphone pour diffuser l’audio directement depuis le microphone de l’utilisateur. La connexion gère automatiquement getUserMedia et l’encodage audio.

const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
microphone: {
deviceId: "optional-device-id",
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
});
PropriétéTypeDescription
deviceIdstringID d’un périphérique microphone spécifique.
echoCancellationbooleanActive l’annulation d’écho.
noiseSuppressionbooleanActive la réduction du bruit.
autoGainControlbooleanActive le contrôle automatique du gain.

Options audio manuelles

Transmettez audioFormat et sampleRate pour envoyer manuellement des données audio via connection.send().

import { AudioFormat } from "@elevenlabs/client";
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
});
PropriétéTypeDescription
audioFormatAudioFormatFormat d’encodage audio (par exemple, AudioFormat.PCM_16000).
sampleRatenumberFréquence d’échantillonnage en Hz. Doit correspondre à audioFormat.

Énumération 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",
}

Mode microphone

Diffusez l’audio directement depuis le microphone de l’utilisateur :

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

Mode audio manuel (transcription de fichier)

Transcrivez des fichiers audio préenregistrés en envoyant manuellement les données 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() renvoie une instance RealtimeConnection avec les méthodes suivantes.

on(event, listener)

Enregistrez un écouteur d’événements. Consultez Événements pour connaître les types d’événements disponibles.

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

off(event, listener)

Supprimez un écouteur d’événements précédemment enregistré.

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

send(data)

Envoyez des données audio à Scribe (mode audio manuel uniquement).

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

Le champ previousText ne peut être envoyé que dans le premier fragment audio d’une session. Son envoi dans les fragments suivants génère une erreur.

commit()

Validez manuellement la transcription actuelle. Nécessaire uniquement avec CommitStrategy.MANUAL.

connection.commit();

close()

Fermez la connexion WebSocket et libérez les ressources (flux du microphone, contexte audio).

connection.close();

Événements

Enregistrez des écouteurs d’événements à l’aide de connection.on(event, listener). Tous les événements sont disponibles sous forme de constantes dans l’énumération RealtimeEvents.

Événements de transcription

ÉvénementDonnéesDescription
SESSION_STARTED{ session_id: string }Session Scribe démarrée.
PARTIAL_TRANSCRIPT{ text: string }Résultat de transcription provisoire.
COMMITTED_TRANSCRIPT{ text: string }Résultat de transcription finalisé.
COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS{ text: string; language_code?: string; words?: WordsItem[] }Résultat finalisé avec minutage par mot.

Le type WordsItem contient les informations de minutage au niveau des mots :

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
}

Événements de connexion

ÉvénementDonnéesDescription
OPENEventConnexion WebSocket ouverte.
CLOSEEventConnexion WebSocket fermée.
ERRORError | EventErreur générique.

Événements d’erreur

Tous les événements d’erreur reçoivent { error: string }.

ÉvénementDescription
AUTH_ERRORErreur d’authentification.
QUOTA_EXCEEDEDQuota d’utilisation dépassé.
COMMIT_THROTTLEDRequête de validation limitée.
TRANSCRIBER_ERRORErreur du moteur de transcription.
UNACCEPTED_TERMSConditions d’utilisation non acceptées.
RATE_LIMITEDLimite de débit atteinte.
INPUT_ERRORFormat d’entrée non valide.
QUEUE_OVERFLOWFile de traitement pleine.
RESOURCE_EXHAUSTEDRessources serveur à pleine capacité.
SESSION_TIME_LIMIT_EXCEEDEDDurée maximale de session atteinte.
CHUNK_SIZE_EXCEEDEDFragment audio trop volumineux.
INSUFFICIENT_AUDIO_ACTIVITYActivité audio insuffisante pour maintenir la connexion.

Stratégies de validation

Contrôlez le moment où les transcriptions sont validées :

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

Pour en savoir plus, consultez Transcriptions et stratégies de validation.

Exemple complet

Voici un exemple complet qui transcrit l’audio du microphone avec une stratégie de validation basée sur le 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);