> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Strömning på klientsidan

> **Note**
>
> **Guide** · Förutsätter att du har slutfört [snabbstartsguiden för Speech to Text ](/docs/sv/eleven-api/guides/cookbooks/speech-to-text).

## Översikt

ElevenLabs Realtime Speech to Text API låter dig transkribera ljudströmmar i realtid med extremt låg fördröjning med modellen Scribe Realtime v2. Oavsett om du bygger röstassistenter, transkriptionstjänster eller andra program som kräver liveigenkänning av tal levererar detta WebSocket-baserade API partiella transkriptioner medan du talar och bekräftade transkriptioner när talsegment är klara.

Scribe v2 Realtime kan implementeras på klientsidan för att transkribera ljud i realtid, antingen via mikrofonen eller genom att manuellt dela upp ljudet i segment.

Implementeringen på klientsidan skiljer sig från serversidan på några sätt:

* Kräver en engångstoken – en tillfällig token som kan användas för att ansluta till API:et utan att exponera din API-nyckel.
* Ljud från mikrofonen kan skickas direkt till API:et för transkribering, utan att du behöver dela upp ljudet manuellt i segment.

För att strömma ljud från en URL, se guiden [Strömning på serversidan](/docs/sv/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming).

## Snabbstart

> **Note**
>
> Den här guiden förutsätter att du har [konfigurerat din API-nyckel](/docs/sv/eleven-api/quickstart). Slutför
> snabbstartsguiden först om du inte redan har gjort det.

#### Installera SDK:t

**`React`**

```bash title="React"
npm install @elevenlabs/react @elevenlabs/elevenlabs-js
```

**`JavaScript`**

```bash title="JavaScript"
npm install @elevenlabs/client @elevenlabs/elevenlabs-js
```

#### Skapa en token

För att använda SDK:t på klientsidan behöver du skapa en engångstoken. Det är en tillfällig token som kan användas för att ansluta till API:et utan att exponera din API-nyckel. Det kan göras via ElevenLabs API på serversidan.

> **Warning**
>
> Exponera aldrig din API-nyckel för klienten.

```typescript
// Node.js server
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

app.get("/scribe-token", yourAuthMiddleware, async (req, res) => {
  const token = await elevenlabs.tokens.singleUse.create("realtime_scribe");

  res.json(token);
});
```

> **Info**
>
> En engångstoken upphör automatiskt att gälla efter 15 minuter.

#### Starta transkriberingssessionen

Transkribering kan göras antingen via mikrofonen eller genom att manuellt dela upp ditt eget ljud i segment. Ditt eget ljud kan vara en fil eller en ström.

> **Info**
>
> En fullständig lista över parametrar och alternativ som API:et stöder finns i [API-referensen](/docs/sv/api-reference/speech-to-text/v-1-speech-to-text-realtime).

#### Mikrofon

**`React`**

```typescript title="React"
import { useScribe } from "@elevenlabs/react";

function MyComponent() {
  const scribe = useScribe({
    modelId: "scribe_v2_realtime",
    onPartialTranscript: (data) => {
      console.log("Partial:", data.text);
    },
    onCommittedTranscript: (data) => {
      console.log("Committed:", data.text);
    },
    onCommittedTranscriptWithTimestamps: (data) => {
      console.log("Committed with timestamps:", data.text);
      console.log("Timestamps:", data.words);
    },
  });

  const handleStart = async () => {
    // Fetch a single use token from the server
    const token = await fetchTokenFromServer();

    await scribe.connect({
      token,
      microphone: {
        echoCancellation: true,
        noiseSuppression: true,
      },
    });
  };

  return (
    <div>
      <button onClick={handleStart} disabled={scribe.isConnected}>
        Start Recording
      </button>
      <button onClick={scribe.disconnect} 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>
  );
}
```

**`JavaScript`**

```typescript title="JavaScript"
// Client side
import { Scribe, RealtimeEvents } from "@elevenlabs/client";

// Ensure you have authentication headers set up
const response = await fetch("/scribe-token", yourAuthHeaders);
const { token } = await response.json();

const connection = Scribe.connect({
  token,
  modelId: "scribe_v2_realtime",
  includeTimestamps: true,
  microphone: {
    echoCancellation: true,
    noiseSuppression: true,
    autoGainControl: true,
  },
});

// Set up event handlers

// Session started
connection.on(RealtimeEvents.SESSION_STARTED, () => {
  console.log("Session started");
});

// Partial transcripts (interim results), use this in your UI to show the live transcript
connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) => {
  console.log("Partial:", data.text);
});

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

// Committed transcripts with word-level timestamps. Only received when includeTimestamps is set to true.
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS, (data) => {
  console.log("Committed:", data.text);
  console.log("Timestamps:", data.words);
});

// Errors - will catch all errors, both server and websocket specific errors
connection.on(RealtimeEvents.ERROR, (error) => {
  console.error("Error:", error);
});

// Connection opened
connection.on(RealtimeEvents.OPEN, () => {
  console.log("Connection opened");
});

// Connection closed
connection.on(RealtimeEvents.CLOSE, () => {
  console.log("Connection closed");
});

// When you are done, close the connection
connection.close();
```

#### Manuell uppdelning av ljudsegment

**`React`**

```typescript title="React"
import { useScribe, AudioFormat } from "@elevenlabs/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;

    // Fetch a single use token from the server
    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>
  );
}
```

**`JavaScript`**

```typescript title="JavaScript"
import { Scribe, AudioFormat, RealtimeEvents, CommitStrategy } from "@elevenlabs/client";

// Ensure you have authentication headers set up
const response = await fetch("/scribe-token", yourAuthHeaders);
const { token } = await response.json();

const connection = Scribe.connect({
  token,
  modelId: "scribe_v2_realtime",
  includeTimestamps: true,
  audioFormat: AudioFormat.PCM_16000,
  sampleRate: 16000,
  commitStrategy: CommitStrategy.MANUAL,
});

// Set up event handlers
connection.on(RealtimeEvents.SESSION_STARTED, () => {
  console.log("Session started");
  sendAudio();
});

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

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

connection.on(RealtimeEvents.ERROR, (error) => {
  console.error("Error:", error);
});

// Committed transcripts with word-level timestamps. Only received when includeTimestamps is set to true.
connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS, (data) => {
  console.log("Committed:", data.text);
  console.log("Timestamps:", data.words);

  // Committed transcript received, close the connection
  connection.close();
});

async function sendAudio() {
  // Get file from input element
  const fileInput = document.querySelector('input[type="file"]');
  const audioFile = fileInput.files[0];

  // Read file as ArrayBuffer
  const arrayBuffer = await audioFile.arrayBuffer();
  const audioData = new Uint8Array(arrayBuffer);

  // Convert to base64 and send in chunks
  const chunkSize = 8192; // 8KB chunks
  for (let i = 0; i < audioData.length; i += chunkSize) {
    const chunk = audioData.slice(i, i + chunkSize);
    const base64 = btoa(String.fromCharCode(...chunk));

    // Send audio chunk
    connection.send({ audioBase64: base64 });

    // Optional: Add delay to simulate real-time streaming
    await new Promise((resolve) => setTimeout(resolve, 100));
  }

  // Signal end of audio segment
  connection.commit();
}
```

## Nästa steg

#### [Strömning på serversidan](/docs/sv/eleven-api/guides/how-to/speech-to-text/realtime/server-side-streaming)

Transkribera ljudströmmar på serversidan med samma WebSocket API.

#### [Transkriptioner och bekräftelsestrategier](/docs/sv/eleven-api/guides/how-to/speech-to-text/realtime/transcripts-and-commit-strategies)

Styr när transkriptioner bekräftas och hur partiella resultat hanteras.