> ## Documentation Index
> Fetch the complete documentation index at: https://assembly-preview.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Transcribe an Audio File

> Learn how to transcribe and analyze an audio file.

<Note>
  Universal-2 is live
  Dive into our research paper to see how we're redefining speech AI accuracy. Read more [here](https://www.assemblyai.com/research/universal-2).
</Note>

## Overview

By the end of this tutorial, you'll be able to:

* Transcribe an audio file.
* Enable [Speaker Diarization](/docs/speech-to-text/speaker-diarization) to detect speakers in an audio file.

Here's the full sample code for what you'll build in this tutorial:

<CodeGroup>
  ```python Python theme={"system"}
  import assemblyai as aai

  aai.settings.api_key = "YOUR_API_KEY"

  transcriber = aai.Transcriber()

  # You can use a local filepath:
  # audio_file = "./example.mp3"

  # Or use a publicly-accessible URL:
  audio_file = (
      "https://assembly.ai/sports_injuries.mp3"
  )

  config = aai.TranscriptionConfig(speaker_labels=True)

  transcript = transcriber.transcribe(audio_file, config)

  if transcript.status == aai.TranscriptStatus.error:
      print(f"Transcription failed: {transcript.error}")
      exit(1)

  print(transcript.text)

  for utterance in transcript.utterances:
      print(f"Speaker {utterance.speaker}: {utterance.text}")
  ```

  ```typescript typescript theme={"system"}
  import { AssemblyAI } from 'assemblyai'

  const client = new AssemblyAI({
    apiKey: 'YOUR_API_KEY'
  })

  // You can use a local filepath:
  // const audioFile = "./example.mp3"

  // Or use a publicly-accessible URL:
  const audioFile = 'https://assembly.ai/sports_injuries.mp3'

  const params = {
    audio: audioFile,
    speaker_labels: true
  }

  const run = async () => {
    const transcript = await client.transcripts.transcribe(params)

    if (transcript.status === 'error') {
      console.error(`Transcription failed: ${transcript.error}`)
      process.exit(1)
    }

    console.log(transcript.text)

    for (let utterance of transcript.utterances!) {
      console.log(`Speaker ${utterance.speaker}: ${utterance.text}`)
    }
  }

  run()
  ```

  ```go Go theme={"system"}
  package main

  import (
      "context"
      "fmt"
      "os"

      aai "github.com/AssemblyAI/assemblyai-go-sdk"
  )

  func main() {
      ctx := context.Background()

      client := aai.NewClient("YOUR_API_KEY")

      params := &aai.TranscriptOptionalParams{
          SpeakerLabels: aai.Bool(true),
      }

      // You can use a local file:
      /*
      f, err := os.Open("./example.mp3")
      [error handling here]
      transcript, err := client.Transcripts.TranscribeFromReader(ctx, f, params)
      */

      // Or use a publicly-accessible URL:
      audioURL := "https://assembly.ai/sports_injuries.mp3"

      transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, params)
      if err != nil {
          fmt.Println("Something bad happened:", err)
          os.Exit(1)
      }

      fmt.Println(*transcript.Text)

      for _, utterance := range transcript.Utterances {
          fmt.Printf("Speaker %v: %v\n", *utterance.Speaker, *utterance.Text)
      }
  }
  ```

  ```java Java theme={"system"}
  import com.assemblyai.api.AssemblyAI;
  import com.assemblyai.api.resources.transcripts.types.*;

  public final class App {
      public static void main(String[] args) {
          AssemblyAI client = AssemblyAI.builder()
                  .apiKey("YOUR_API_KEY")
                  .build();

          var params = TranscriptOptionalParams.builder()
                  .speakerLabels(true)
                  .build();

          // You can use a local file:
          /*
          Transcript transcript = aai.transcripts().transcribe(
                  new File("./example.mp3"), params);
          */

          // Or use a publicly-accessible URL:
          String audioUrl = "https://assembly.ai/sports_injuries.mp3";
          Transcript transcript = client.transcripts().transcribe(audioUrl, params);

          if (transcript.getStatus().equals(TranscriptStatus.ERROR)) {
            System.err.println(transcript.getError().get());
            System.exit(1);
          }

          System.out.println(transcript.getText().get());

          transcript.getUtterances().get().forEach(utterance ->
                  System.out.println("Speaker " + utterance.getSpeaker() + ": " + utterance.getText())
          );
      }
  }
  ```

  ```csharp C# theme={"system"}
  using AssemblyAI;
  using AssemblyAI.Transcripts;

  var client = new AssemblyAIClient("YOUR_API_KEY");

  // You can use a local file:
  /*
  var transcript = await client.Transcripts.TranscribeAsync(
      new FileInfo("./example.mp3"),
      new TranscriptOptionalParams
      {
          SpeakerLabels = true
      }
  );
  */

  // Or use a publicly-accessible URL:
  const string audioUrl = "https://assembly.ai/sports_injuries.mp3";

  var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
  {
      AudioUrl = audioUrl,
      SpeakerLabels = true
  });

  if (transcript.Status == TranscriptStatus.Error)
  {
      Console.WriteLine(transcript.Error);
      Environment.Exit(1);
  }

  // Alternatively, you can use the EnsureStatusCompleted() method
  // to throw an exception if the transcription status is not "completed".
  // transcript.EnsureStatusCompleted();

  Console.WriteLine(transcript.Text);

  foreach (var utterance in transcript.Utterances!)
  {
      Console.WriteLine($"Speaker {utterance.Speaker}: {utterance.Text}");
  }
  ```

  ```ruby Ruby theme={"system"}
  require 'assemblyai'

  client = AssemblyAI::Client.new(api_key: 'YOUR_API_KEY')

  # You can upload and transcribe a local file:
  # uploaded_file = client.files.upload(file: '/path/to/your/file')
  # transcript = client.transcripts.transcribe(audio_url: uploaded_file.upload_url, speaker_labels: true)

  # Or use a publicly-accessible URL:
  audio_url = 'https://assembly.ai/sports_injuries.mp3'

  transcript = client.transcripts.transcribe(
    audio_url: audio_url,
    speaker_labels: true
  )

  abort transcript.error if transcript.status == AssemblyAI::Transcripts::TranscriptStatus::ERROR

  puts transcript.text

  transcript.utterances.each do |utterance|
    printf('Speaker %<speaker>s: %<text>s', speaker: utterance.speaker, text: utterance.text)
  end
  ```
</CodeGroup>

## Before you begin

To complete this tutorial, you need:

* [Python](https://www.python.org/), [TypeScript](https://www.typescriptlang.org/), [Go](https://go.dev), Java, [.NET](https://dotnet.microsoft.com/en-us/download), or [Ruby](https://www.ruby-lang.org/en/documentation/installation/) installed.
* A [free AssemblyAI account](https://www.assemblyai.com/dashboard/signup).

## Step 1: Install the SDK

Install the package via pip:

<CodeGroup>
  ```sh Python theme={"system"}
  pip install assemblyai
  ```

  ```sh Typescript theme={"system"}
  npm install assemblyai
  ```

  ```sh Go theme={"system"}
  go get github.com/AssemblyAI/assemblyai-go-sdk
  ```

  ```xml Java theme={"system"}
  dependencies {
      implementation 'com.assemblyai:assemblyai-java:ASSEMBLYAI_SDK_VERSION'
  }
  ```

  ```bash C# theme={"system"}
  <PackageReference Include="AssemblyAI" Version="ASSEMBLYAI_SDK_VERSION" />
  ```

  ```ruby Ruby theme={"system"}
  gem install assemblyai
  ```
</CodeGroup>

## Step 2: Configure the SDK

In this step, you 'll create an SDK client and configure it to use your API key.

<Steps>
  <Step>
    Browse to [Account](https://www.assemblyai.com/app/account), and then click the text under **Your API key** to copy it.
  </Step>

  <Step>
    Create a new `Transcriber` and configure it to use your API key. Replace `YOUR_API_KEY` with your copied API key.

    <CodeGroup>
      ```python Python theme={"system"}
      import assemblyai as aai

      aai.settings.api_key = "YOUR_API_KEY"

      transcriber = aai.Transcriber()
      ```

      ```typescript Typescript theme={"system"}
      import { AssemblyAI } from 'assemblyai'

      const client = new AssemblyAI({
        apiKey: 'YOUR_API_KEY'
      })
      ```

      ```go Go theme={"system"}
      package main

      import (
          aai "github.com/AssemblyAI/assemblyai-go-sdk"
      )

      func main() {
          client := aai.NewClient("YOUR_API_KEY")
      }
      ```

      ```java Java theme={"system"}
      import com.assemblyai.api.AssemblyAI;
      import com.assemblyai.api.resources.transcripts.types.*;

      AssemblyAI client = AssemblyAI.builder()
                      .apiKey("YOUR_API_KEY")
                      .build();
      ```

      ```csharp C# theme={"system"}
      using AssemblyAI;
      using AssemblyAI.Transcripts;

      var client = new AssemblyAIClient("YOUR_API_KEY");
      ```

      ```ruby Ruby theme={"system"}
      require 'assemblyai'

      client = AssemblyAI::Client.new(api_key: 'YOUR_API_KEY')
      ```
    </CodeGroup>
  </Step>
</Steps>

## Step 3: Submit audio for transcription

In this step, you'll submit the audio file for transcription and wait until it's completes. The time it takes to process an audio file depends on its duration and the enabled models. Most transcriptions complete within 45 seconds.

<Steps>
  <Step>
    Specify a URL to the audio you want to transcribe. The URL needs to be accessible from AssemblyAI's servers. For a list of supported formats, see [FAQ](/docs/concepts/faq).

    <CodeGroup>
      ```python Python theme={"system"}
      audio_file = "https://assembly.ai/sports_injuries.mp3"
      ```

      ```typescript Typescript theme={"system"}
      const audioFile = 'https://assembly.ai/sports_injuries.mp3'
      ```

      ```go Go theme={"system"}
      audioURL := "https://assembly.ai/sports_injuries.mp3"
      ```

      ```java Java theme={"system"}
      String audioUrl = "https://assembly.ai/sports_injuries.mp3";
      ```

      ```csharp C# theme={"system"}
      const string audioUrl = "https://assembly.ai/sports_injuries.mp3";
      ```

      ```ruby Ruby theme={"system"}
      audio_url = 'https://assembly.ai/sports_injuries.mp3'
      ```
    </CodeGroup>

    <Info>
      Local audio files

      If you want to use a local file, you can also specify a local path, for example:

      ```python theme={"system"}
      audio_file = "./example.mp3"
      ```
    </Info>

    <Info>
      YouTube

      YouTube URLs are not supported. If you want to transcribe a YouTube video, you need to download the audio first.
    </Info>
  </Step>

  <Step>
    To generate the transcript, pass the audio URL to `transcribe()`.

    This may take a minute while we're processing the audio.

    <CodeGroup>
      ```python Python theme={"system"}
      transcript = transcriber.transcribe(audio_file)
      ```

      ```typescript Typescript theme={"system"}
      const transcript = await client.transcripts.transcribe({ audio: audioFile })
      ```

      ```go Go theme={"system"}
      transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, nil)
      ```

      ```java Java theme={"system"}
      Transcript transcript = client.transcripts().transcribe(audioUrl);
      ```

      ```csharp C# theme={"system"}
      var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
      {
          AudioUrl = audioUrl
      });
      ```

      ```ruby Ruby theme={"system"}
      transcript = client.transcripts.transcribe(audio_url: audio_url)
      ```
    </CodeGroup>

    <Tip>
      Select the speech model

      You can select the class of models to use in order to make cost-performance tradeoffs best suited for your application. See [Select the speech model](/docs/speech-to-text/speech-recognition#select-the-speech-model-with-best--nano).
    </Tip>
  </Step>

  <Step>
    If the transcription failed, the `status` of the transcription will be set to `error`. To see why it failed you can print the value of `error`.

    <CodeGroup>
      ```python Python theme={"system"}
      if transcript.error:
          print(transcript.error)
          exit(1)
      ```

      ```typescript Typescript theme={"system"}
      if (transcript.status === 'error') {
          console.error(transcript.error)
          process.exit(1)
      }
      ```

      ```go Go theme={"system"}
      if err != nil {
          fmt.Println("Something bad happened:", err)
          os.Exit(1)
      }
      ```

      ```java Java theme={"system"}
      if (transcript.getStatus().equals(TranscriptStatus.ERROR)) {
          System.err.println(transcript.getError().get());
          System.exit(1);
      }
      ```

      ```csharp C# theme={"system"}
      if (transcript.Status == TranscriptStatus.Error)
      {
          Console.WriteLine(transcript.Error);
          Environment.Exit(1);
      }

      // Alternatively, you can use the EnsureStatusCompleted() method
      // to throw an exception if the transcription status is not "completed".
      // transcript.EnsureStatusCompleted();
      ```

      ```ruby Ruby theme={"system"}
      abort transcript.error if transcript.status == AssemblyAI::Transcripts::TranscriptStatus::ERROR
      ```
    </CodeGroup>
  </Step>

  <Step>
    Print the complete transcript.

    <CodeGroup>
      ```python Python theme={"system"}
      print(transcript.text)
      ```

      ```typescript Typescript theme={"system"}
      console.log(transcript.text)
      ```

      ```go Go theme={"system"}
      fmt.Println(*transcript.Text)
      ```

      ```java Java theme={"system"}
      System.out.println(transcript.getText().get());
      ```

      ```csharp C# theme={"system"}
      Console.WriteLine(transcript.Text);
      ```

      ```ruby Ruby theme={"system"}
      puts transcript.text
      ```
    </CodeGroup>
  </Step>

  <Step>
    Run the application and wait for it to finish.

    You've successfully transcribed your first audio file. You can see all submitted transcription jobs in the [Processing queue](https://www.assemblyai.com/app/processing-queue).
  </Step>
</Steps>

## Step 4: Enable additional AI models

You can extract even more insights from the audio by enabling any of our [AI models](/docs/audio-intelligence) using *transcription options*. In this step, you'll enable the [Speaker diarization](/docs/speech-to-text/speaker-diarization) model to detect who said what.

<Steps>
  <Step>
    Create a `TranscriptionConfig` with `speaker_labels` set to `True`, and then pass it as the second argument to `transcribe()`.

    <CodeGroup>
      ```python Python theme={"system"}
      config = aai.TranscriptionConfig(speaker_labels=True)
      transcript = transcriber.transcribe(audio_file, config)
      ```

      ```typescript Typescript theme={"system"}
      const params = {  audio: audioFile,  speaker_labels: true}
      const transcript = await client.transcripts.transcribe(params)
      ```

      ```go Go theme={"system"}
      params := &assemblyai.TranscriptOptionalParams{
          SpeakerLabels: aai.Bool(true),
      }

      transcript, err := client.Transcripts.TranscribeFromURL(ctx, audioURL, params)
      ```

      ```java Java theme={"system"}
      var params = TranscriptOptionalParams.builder()
                      .speakerLabels(true)
                      .build();

      Transcript transcript = client.transcripts().transcribe(audioUrl, params);
      ```

      ```csharp C# theme={"system"}
      var transcript = await client.Transcripts.TranscribeAsync(new TranscriptParams
      {
          AudioUrl = audioUrl,
          SpeakerLabels = true
      });
      ```

      ```ruby Ruby theme={"system"}
      transcript = client.transcripts.transcribe(
        audio_url: audio_url,
        speaker_labels: true
      )
      ```
    </CodeGroup>
  </Step>

  <Step>
    In addition to the full transcript, you now have access to utterances from each speaker.

    <CodeGroup>
      ```python Python theme={"system"}
      for utterance in transcript.utterances:
          print(f"Speaker {utterance.speaker}: {utterance.text}")
      ```

      ```typescript Typescript theme={"system"}
      for (let utterance of transcript.utterances!) {
          console.log(`Speaker ${utterance.speaker}: ${utterance.text}`)
      }
      ```

      ```go Go theme={"system"}
      for _, utterance := range transcript.Utterances {
          fmt.Printf("Speaker %v: %v\n", *utterance.Speaker, *utterance.Text)
      }
      ```

      ```java Java theme={"system"}
      transcript.getUtterances().get().forEach(utterance ->
              System.out.println("Speaker " + utterance.getSpeaker() + ": " + utterance.getText())
      );
      ```

      ```csharp C# theme={"system"}
      foreach (var utterance in transcript.Utterances!)
      {
          Console.WriteLine($"Speaker {utterance.Speaker}: {utterance.Text}");
      }
      ```

      ```ruby Ruby theme={"system"}
      transcript.utterances.each do |utterance|
        printf('Speaker %<speaker>s: %<text>s', speaker: utterance.speaker, text: utterance.text)
      end
      ```
    </CodeGroup>
  </Step>
</Steps>

Many of the properties in the transcript object only become available after you enable the corresponding model. For more information, see the models under [Speech-to-Text](/docs/speech-to-text) and [Audio Intelligence](/docs/audio-intelligence).

## Next steps

In this tutorial, you've learned how to generate a transcript for an audio file and how to extract speaker information by enabling the [Speaker diarization](/docs/speech-to-text/speaker-diarization) model.

Want to learn more?

* For more ways to analyze your audio data, explore our [Audio Intelligence models](/docs/audio-intelligence).
* If you want to transcribe audio in real-time, see [Transcribe streaming audio from a microphone](/docs/getting-started/transcribe-streaming-audio-from-a-microphone).
* To search, summarize, and ask questions on your transcripts with LLMs, see [LeMUR](/docs/lemur).

## Need some help?

If you get stuck, or have any other questions, we'd love to help you out. Ask our support team in our [Discord server](https://discord.gg/aSMMpMadFh).
