{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ur8xi4C7S06n"
      },
      "outputs": [],
      "source": [
        "# Copyright 2025 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JAPoU8Sm5E6e"
      },
      "source": [
        "# Get started with Chirp 3 Transcription\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Faudio%2Fspeech%2Fgetting-started%2Fget_started_with_chirp_3_transcription.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\">\n",
        "      <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/audio/speech/getting-started/get_started_with_chirp_3_transcription.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>            "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "84f0f73a0f76"
      },
      "source": [
        "| Authors |\n",
        "| --- |\n",
        "| [Katie Nguyen](https://github.com/katiemn) |\n",
        "| [Holt Skinner](https://github.com/holtskinner) |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tvgnzT1CKxrO"
      },
      "source": [
        "## Overview\n",
        "\n",
        "### Chirp 3\n",
        "\n",
        "This notebook introduces [Chirp 3](https://cloud.google.com/speech-to-text/v2/docs/chirp_3-model), Google's model for converting speech to text in multiple languages.\n",
        "\n",
        "In this tutorial, you'll learn how to use the Speech-to-Text API V2 to:\n",
        "\n",
        "- Transcribe an audio file with batch speech recognition\n",
        "- Perform a language-agnostic transcription\n",
        "- Use Chirp 3 for speaker diarization\n",
        "- Perform streaming speech recognition"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "61RBz8LLbxCR"
      },
      "source": [
        "## Get started"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "No17Cw5hgx12"
      },
      "source": [
        "### Install the Speech SDK and other required packages\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "tFy3H3aPgx12"
      },
      "outputs": [],
      "source": [
        "%pip install --upgrade --quiet google-cloud-speech ipywebrtc"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dmWOrTJ3gx13"
      },
      "source": [
        "### Authenticate your notebook environment (Colab only)\n",
        "\n",
        "If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "NyKGtVQjgx13"
      },
      "outputs": [],
      "source": [
        "import sys\n",
        "\n",
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import auth\n",
        "\n",
        "    auth.authenticate_user()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5303c05f7aa6"
      },
      "source": [
        "### Import libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qqm0OQpAYCph"
      },
      "outputs": [],
      "source": [
        "import json\n",
        "import os\n",
        "import re\n",
        "\n",
        "from IPython.display import HTML, Audio, display\n",
        "from typing import Generator\n",
        "from google.api_core.client_options import ClientOptions\n",
        "from google.cloud.speech_v2 import SpeechClient\n",
        "from google.cloud.speech_v2.types import cloud_speech\n",
        "from ipywebrtc import AudioRecorder, CameraStream"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DF4l8DTdWgPY"
      },
      "source": [
        "### Set Google Cloud project information\n",
        "\n",
        "To get started using the Speech-to-Text API, you must have an existing Google Cloud project and [enable the API](https://console.cloud.google.com/flows/enableapi?apiid=speech.googleapis.com).\n",
        "\n",
        "Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment).\n",
        "\n",
        "Please note the **available regions** for Chirp 3, see [documentation](https://cloud.google.com/speech-to-text/v2/docs/chirp_3-model#regional_availability)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "WIQyBhAn_9tK"
      },
      "outputs": [],
      "source": [
        "# fmt: off\n",
        "PROJECT_ID = \"[your-project-id]\"  # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
        "# fmt: on\n",
        "if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
        "    PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
        "\n",
        "STT_LOCATION = \"us\"  # @param {type: \"string\"}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "cR5PafOSrV2W"
      },
      "outputs": [],
      "source": [
        "! gcloud config set project {PROJECT_ID}\n",
        "! gcloud auth application-default login -q\n",
        "! gcloud auth application-default set-quota-project {PROJECT_ID}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sP8GBj3tBAC1"
      },
      "source": [
        "### Create client\n",
        "\n",
        "Initiate the API endpoint and the Speech-to-Text client and define key constants."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "rXTVeU1uBBqY"
      },
      "outputs": [],
      "source": [
        "client = SpeechClient(\n",
        "    client_options=ClientOptions(api_endpoint=f\"{STT_LOCATION}-speech.googleapis.com\")\n",
        ")\n",
        "recognizer = client.recognizer_path(PROJECT_ID, STT_LOCATION, \"_\")\n",
        "model = \"chirp_3\"\n",
        "# Set a timeout for the batch recognition operation\n",
        "MAX_AUDIO_LENGTH_SECS = 8 * 60 * 60"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "M7WQQFp_RvGH"
      },
      "source": [
        "### Define helper functions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "pWrNWdV_RxGn"
      },
      "outputs": [],
      "source": [
        "def print_transcript(results: list[cloud_speech.SpeechRecognitionResult]) -> None:\n",
        "    for result in results:\n",
        "        display(\n",
        "            HTML(\n",
        "                f\"\"\"<div style=\"word-break: break-all;\">{result.alternatives[0].transcript}</div>\"\"\"\n",
        "            )\n",
        "        )\n",
        "\n",
        "\n",
        "def generate_audio_chunks(\n",
        "    audio_content: bytes, chunk_size: int\n",
        ") -> Generator[bytes, None, None]:\n",
        "    \"\"\"Splits a byte string (like audio data) into smaller, equal-sized chunks.\n",
        "\n",
        "    Args:\n",
        "        audio_content: The raw byte data of the audio.\n",
        "        chunk_size: The desired size for each audio chunk in bytes.\n",
        "\n",
        "    Yields:\n",
        "        A series of audio chunks.\n",
        "    \"\"\"\n",
        "    # Loop through the audio content, stepping by chunk_size each time\n",
        "    for start_index in range(0, len(audio_content), chunk_size):\n",
        "        # The end_index is the start_index plus the chunk size\n",
        "        end_index = start_index + chunk_size\n",
        "        # Yield the slice of audio data for the current chunk\n",
        "        yield audio_content[start_index:end_index]\n",
        "\n",
        "\n",
        "def group_utterances_by_speaker_from_file(json_file_path: str) -> dict:\n",
        "    \"\"\"Reads a JSON file containing transcribed words and groups them into sentences spoken by each speaker.\"\"\"\n",
        "    with open(json_file_path, encoding=\"utf-8\") as f:\n",
        "        json_data_string = f.read()\n",
        "    words_regex = r'\"words\":\\s*(\\[.*?\\])'\n",
        "    match = re.search(words_regex, json_data_string, re.DOTALL)\n",
        "\n",
        "    words_list = json.loads(match.group(1))\n",
        "    dialogue = []\n",
        "    current_speaker = None\n",
        "    current_utterance_words = []\n",
        "    current_speaker = words_list[0][\"speakerLabel\"]\n",
        "\n",
        "    for item in words_list:\n",
        "        word = item[\"word\"]\n",
        "        speaker = item[\"speakerLabel\"]\n",
        "        # Check if the speaker has changed\n",
        "        if speaker != current_speaker:\n",
        "            dialogue.append(\n",
        "                {\"speaker\": current_speaker, \"text\": \" \".join(current_utterance_words)}\n",
        "            )\n",
        "            # Start a new utterance\n",
        "            current_speaker = speaker\n",
        "            current_utterance_words = [word]\n",
        "        else:\n",
        "            # Continue the current utterance\n",
        "            current_utterance_words.append(word)\n",
        "    # Add the final pending utterance\n",
        "    if current_speaker is not None:\n",
        "        dialogue.append(\n",
        "            {\"speaker\": current_speaker, \"text\": \" \".join(current_utterance_words)}\n",
        "        )\n",
        "\n",
        "    return {\"dialogue\": dialogue}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VPVDNRyVxquo"
      },
      "source": [
        "## Transcribe using Chirp 3\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LfBiMs0bNwhV"
      },
      "source": [
        "### Online/Synchronous speech recognition\n",
        "\n",
        "You can use online (synchronous) speech recognition for audio files less than 1 minute long.\n",
        "For this first request, Run the following cell to download and play the audio you'll be transcribing. If you'd like to use a different audio clip, modify the `audio_url` variable below."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "yE_-iirV7UDA"
      },
      "outputs": [],
      "source": [
        "audio_url = \"https://storage.googleapis.com/cloud-samples-data/generative-ai/audio/audio_summary_clean_energy_short.mp3\"\n",
        "audio_filename = os.path.basename(audio_url)\n",
        "! wget {audio_url} -O {audio_filename}\n",
        "\n",
        "display(Audio(filename=audio_filename))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lAfgmnZyPo1f"
      },
      "source": [
        "Now, you'll send the `recognize` request. The transcription will be returned as part of the response and displayed in HTML for better visualization in this notebook."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "egBk4a3t0lUD"
      },
      "outputs": [],
      "source": [
        "config = cloud_speech.RecognitionConfig(\n",
        "    auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),\n",
        "    model=model,\n",
        "    language_codes=[\"en-US\"],\n",
        ")\n",
        "\n",
        "with open(audio_filename, \"rb\") as f:\n",
        "    audio_content = f.read()\n",
        "\n",
        "request = cloud_speech.RecognizeRequest(\n",
        "    recognizer=recognizer,\n",
        "    config=config,\n",
        "    content=audio_content,\n",
        ")\n",
        "\n",
        "response = client.recognize(request=request)\n",
        "\n",
        "print_transcript(response.results)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oJSi0bFQQYel"
      },
      "source": [
        "### Perform a language-agnostic transcription\n",
        "\n",
        "In this next request, you'll perform a language-agnostic transcription. This means that Chirp 3 will automatically identify and transcribe the dominant language spoken in the audio, which is essential for multilingual applications.\n",
        "\n",
        "In this next example, you'll use a Spanish audio clip saved in Cloud Storage. To see a full list of the languages available for transcription, check the [documentation](https://cloud.google.com/speech-to-text/v2/docs/chirp_3-model#language_availability_for_transcription)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zcTrgN9xHDXR"
      },
      "outputs": [],
      "source": [
        "audio_url = (\n",
        "    \"https://storage.googleapis.com/cloud-samples-data/generative-ai/audio/spanish.wav\"\n",
        ")\n",
        "audio_gcs_uri = audio_url.replace(\"https://storage.googleapis.com/\", \"gs://\")\n",
        "\n",
        "display(Audio(url=audio_url))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fB4cDExAMCnb"
      },
      "source": [
        "This request is the similar to the previous one, except this time, you'll set `language_codes=[\"auto\"]`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "CphxakXgBEsz"
      },
      "outputs": [],
      "source": [
        "config = cloud_speech.RecognitionConfig(\n",
        "    auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),\n",
        "    model=model,\n",
        "    language_codes=[\"auto\"],\n",
        ")\n",
        "request = cloud_speech.RecognizeRequest(\n",
        "    recognizer=recognizer,\n",
        "    config=config,\n",
        "    uri=audio_gcs_uri,\n",
        ")\n",
        "\n",
        "response = client.recognize(request=request)\n",
        "\n",
        "print_transcript(response.results)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1fOGjzlRMFMw"
      },
      "source": [
        "### Speaker Diarization (Batch Recognition)\n",
        "\n",
        "Chirp 3 also supports speaker diarization, which means it can automatically identify the different speakers in a single-channel audio sample. See the [documentation](https://cloud.google.com/speech-to-text/v2/docs/chirp_3-model#language_availability_for_diarization) for a list of supported available languages for diarization.\n",
        "\n",
        "In this example, you'll also use the `batch_recognize` method to transcribe an audio file in Cloud Storage and save the output in Cloud Storage."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "FosRgcFqEMXX"
      },
      "outputs": [],
      "source": [
        "audio_url = \"https://storage.googleapis.com/cloud-samples-data/generative-ai/audio/Chirp-3-Docs-Dive.mp3\"\n",
        "audio_gcs_uri = audio_url.replace(\"https://storage.googleapis.com/\", \"gs://\")\n",
        "display(Audio(url=audio_url))\n",
        "\n",
        "gcs_output_folder = \"gs://[your-bucket-path]\"  # @param {type: \"string\"}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "eb_gkdN9BvnP"
      },
      "source": [
        "In order to enable speaker diarization, set the `diarization_config` in the `features` parameter of the `RecognitionConfig`.\n",
        "\n",
        "You'll also set your `gcs_output_folder` in a `RecognitionOutputConfig` so the transcription will be saved in Cloud Storage. To display the transcription, you'll copy the output JSON file and use a helper function to format it."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Odgee64-xA2O"
      },
      "outputs": [],
      "source": [
        "config = cloud_speech.RecognitionConfig(\n",
        "    auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),\n",
        "    features=cloud_speech.RecognitionFeatures(\n",
        "        diarization_config=cloud_speech.SpeakerDiarizationConfig(),\n",
        "    ),\n",
        "    model=model,\n",
        "    language_codes=[\"en-US\"],\n",
        ")\n",
        "\n",
        "files = [cloud_speech.BatchRecognizeFileMetadata(uri=audio_gcs_uri)]\n",
        "\n",
        "request = cloud_speech.BatchRecognizeRequest(\n",
        "    recognizer=recognizer,\n",
        "    config=config,\n",
        "    files=files,\n",
        "    recognition_output_config=cloud_speech.RecognitionOutputConfig(\n",
        "        gcs_output_config=cloud_speech.GcsOutputConfig(uri=gcs_output_folder),\n",
        "    ),\n",
        ")\n",
        "operation = client.batch_recognize(request=request)\n",
        "response = operation.result(timeout=MAX_AUDIO_LENGTH_SECS)\n",
        "\n",
        "transcript = response.results[audio_gcs_uri].uri\n",
        "\n",
        "!gsutil cp {transcript} output.json\n",
        "\n",
        "print(json.dumps(group_utterances_by_speaker_from_file(\"output.json\"), indent=4))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yRFD1ByUDuqW"
      },
      "source": [
        "### Streaming speech recognition\n",
        "\n",
        "In the following cells you'll simulate transcribing text from an audio stream. To start, you'll record an audio clip with your microphone by running the following cell."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "K2OrVxHeMxV2"
      },
      "outputs": [],
      "source": [
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import output\n",
        "\n",
        "    output.enable_custom_widget_manager()\n",
        "\n",
        "camera = CameraStream(constraints={\"audio\": True, \"video\": False})\n",
        "recorder = AudioRecorder(stream=camera)\n",
        "recorder"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PXhPcYx2ECJ-"
      },
      "source": [
        "Once the audio is captured and you've stopped recording, you'll use FFmpeg to convert and save the clip to a MP3 file for processing."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "TtS36HTdP1hM"
      },
      "outputs": [],
      "source": [
        "with open(\"recording.webm\", \"wb\") as f:\n",
        "    f.write(recorder.audio.value)\n",
        "\n",
        "!ffmpeg -i recording.webm -vn -ar 44100 -ac 2 -f mp3 recording.mp3\n",
        "audio_file = \"recording.mp3\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "swn2txVDEkSx"
      },
      "source": [
        "Now, you'll read the audio file and generate audio chunks to simulate streaming from a helper function. You'll then use the `streaming_recognize` method to get the transcription from each audio chunk with help from a generator function to correctly structure the data stream."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "lwMRXTlf7q-d"
      },
      "outputs": [],
      "source": [
        "CHUNK_SIZE = 3200\n",
        "\n",
        "recognition_config = cloud_speech.RecognitionConfig(\n",
        "    auto_decoding_config=cloud_speech.AutoDetectDecodingConfig(),\n",
        "    language_codes=[\"auto\"],\n",
        "    model=model,\n",
        ")\n",
        "\n",
        "\n",
        "def create_streaming_requests(\n",
        "    audio_file_path: str,\n",
        ") -> Generator[cloud_speech.StreamingRecognizeRequest, None, None]:\n",
        "    \"\"\"Prepares and yields all necessary requests for streaming speech recognition.\n",
        "\n",
        "    First, it yields the configuration request, then it reads an audio file\n",
        "    and yields its content in chunks.\n",
        "\n",
        "    Args:\n",
        "        audio_file_path: The path to the local audio file.\n",
        "\n",
        "    Yields:\n",
        "        A stream of StreamingRecognizeRequest objects.\n",
        "    \"\"\"\n",
        "    # a. First, yield the initial configuration request.\n",
        "    config_request = cloud_speech.StreamingRecognizeRequest(\n",
        "        recognizer=recognizer,\n",
        "        streaming_config=cloud_speech.StreamingRecognitionConfig(\n",
        "            config=recognition_config,\n",
        "        ),\n",
        "    )\n",
        "    yield config_request\n",
        "\n",
        "    # b. Second, read the audio file and stream it in chunks.\n",
        "    with open(audio_file_path, \"rb\") as f:\n",
        "        audio_content = f.read()\n",
        "\n",
        "    for chunk in generate_audio_chunks(audio_content, CHUNK_SIZE):\n",
        "        yield cloud_speech.StreamingRecognizeRequest(audio=chunk)\n",
        "\n",
        "\n",
        "responses = client.streaming_recognize(requests=create_streaming_requests(audio_file))\n",
        "\n",
        "print(\"Streaming transcripts:\")\n",
        "all_transcripts = []\n",
        "for response in responses:\n",
        "    for result in response.results:\n",
        "        transcript = result.alternatives[0].transcript\n",
        "        print(transcript)\n",
        "        all_transcripts.append(transcript)\n",
        "\n",
        "final_transcript = \" \".join(all_transcripts)\n",
        "print(f\"\\n--- Final Combined Transcript ---\\n{final_transcript}\")"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "get_started_with_chirp_3_transcription.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
