SDK de JavaScript

Scribe: transcripción de voz a texto en tiempo real con JavaScript

Para obtener una visión general de Scribe y sus funciones, consulta la visión general de Voz a Texto . Para ver guías de uso paso a paso, consulta streaming del lado del cliente.

Instalación

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

Usa la skill de voz a texto de ElevenLabs para transcribir audio desde tu asistente de programación con IA:

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

Esta biblioteca se puede usar en cualquier proyecto basado en JavaScript. Si usas React, considera el hook useScribe, que proporciona gestión de estado y control del ciclo de vida integrados.

Uso

Este es un ejemplo funcional mínimo que se conecta a Scribe y registra los resultados de la transcripción:

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

Obtener un token

Scribe requiere un token de un solo uso para la autenticación. Crea una ruta de API en tu servidor:

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

Tu clave de API de ElevenLabs es confidencial. No la expongas nunca al cliente. Genera siempre el token en el servidor.

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

Opciones de conexión

Scribe.connect() acepta opciones de micrófono u opciones de audio manual. Ambas comparten un conjunto común de opciones básicas.

Opciones básicas

PropiedadTipoPredeterminadoDescripción
tokenstringToken de un solo uso para la autenticación de WebSocket.
modelIdstringID del modelo (por ejemplo, "scribe_v2_realtime").
baseUristring"wss://api.elevenlabs.io"URI base personalizada de WebSocket.
commitStrategyCommitStrategy"manual""manual" o "vad".
vadSilenceThresholdSecsnumber1.5Segundos de silencio antes de que VAD confirme (0.3-3.0).
vadThresholdnumber0.4Sensibilidad de VAD (0.1-0.9; los valores menores son más sensibles).
minSpeechDurationMsnumber100Duración mínima de voz en ms (50-2000).
minSilenceDurationMsnumber100Duración mínima de silencio en ms (50-2000).
languageCodestringCódigo de idioma ISO-639-1 o ISO-639-3. Déjalo vacío para la detección automática.
includeTimestampsbooleanfalseRecibe marcas de tiempo por palabra mediante el evento COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS.

Opciones de micrófono

Pasa un objeto microphone para transmitir audio directamente desde el micrófono del usuario. La conexión gestiona getUserMedia y la codificación de audio automáticamente.

const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
microphone: {
deviceId: "optional-device-id",
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true,
},
});
PropiedadTipoDescripción
deviceIdstringID del dispositivo de micrófono específico.
echoCancellationbooleanActiva la cancelación de eco.
noiseSuppressionbooleanActiva la supresión de ruido.
autoGainControlbooleanActiva el control automático de ganancia.

Opciones de audio manual

Pasa audioFormat y sampleRate para enviar datos de audio manualmente mediante connection.send().

import { AudioFormat } from "@elevenlabs/client";
const connection = Scribe.connect({
token,
modelId: "scribe_v2_realtime",
audioFormat: AudioFormat.PCM_16000,
sampleRate: 16000,
});
PropiedadTipoDescripción
audioFormatAudioFormatFormato de codificación de audio (por ejemplo, AudioFormat.PCM_16000).
sampleRatenumberFrecuencia de muestreo en Hz. Debe coincidir con audioFormat.

Enumeración 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",
}

Modo de micrófono

Transmite audio directamente desde el micrófono del usuario:

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

Modo de audio manual (transcripción de archivos)

Transcribe archivos de audio pregrabados enviando los datos de audio manualmente:

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() devuelve una instancia de RealtimeConnection con los siguientes métodos.

on(event, listener)

Registra un listener de eventos. Consulta Eventos para conocer los tipos de eventos disponibles.

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

off(event, listener)

Elimina un listener de eventos registrado anteriormente.

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

send(data)

Envía datos de audio a Scribe (solo en modo de audio manual).

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

El campo previousText solo se puede enviar en el primer fragmento de audio de una sesión. Enviarlo en fragmentos posteriores provoca un error.

commit()

Confirma manualmente la transcripción actual. Solo es necesario al usar CommitStrategy.MANUAL.

connection.commit();

close()

Cierra la conexión WebSocket y libera recursos (flujo del micrófono, contexto de audio).

connection.close();

Eventos

Registra listeners de eventos mediante connection.on(event, listener). Todos los eventos están disponibles como constantes en la enumeración RealtimeEvents.

Eventos de transcripción

EventoDatosDescripción
SESSION_STARTED{ session_id: string }Sesión de Scribe iniciada.
PARTIAL_TRANSCRIPT{ text: string }Resultado de transcripción provisional.
COMMITTED_TRANSCRIPT{ text: string }Resultado de transcripción finalizado.
COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS{ text: string; language_code?: string; words?: WordsItem[] }Resultado finalizado con tiempos por palabra.

El tipo WordsItem contiene información de tiempo por palabra:

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
}

Eventos de conexión

EventoDatosDescripción
OPENEventConexión WebSocket abierta.
CLOSEEventConexión WebSocket cerrada.
ERRORError | EventError genérico.

Eventos de error

Todos los eventos de error reciben { error: string }.

EventoDescripción
AUTH_ERRORError de autenticación.
QUOTA_EXCEEDEDCuota de uso superada.
COMMIT_THROTTLEDSolicitud de confirmación limitada.
TRANSCRIBER_ERRORError del motor de transcripción.
UNACCEPTED_TERMSTérminos de servicio no aceptados.
RATE_LIMITEDLímite de frecuencia alcanzado.
INPUT_ERRORFormato de entrada no válido.
QUEUE_OVERFLOWCola de procesamiento llena.
RESOURCE_EXHAUSTEDRecursos del servidor al límite.
SESSION_TIME_LIMIT_EXCEEDEDSe ha alcanzado el tiempo máximo de sesión.
CHUNK_SIZE_EXCEEDEDFragmento de audio demasiado grande.
INSUFFICIENT_AUDIO_ACTIVITYNo hay suficiente actividad de audio para mantener la conexión.

Estrategias de confirmación

Controla cuándo se confirman las transcripciones:

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

Para más información, consulta Transcripciones y estrategias de confirmación.

Ejemplo completo

Este es un ejemplo completo que transcribe audio del micrófono con una estrategia de confirmación basada en 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);