Course EN
← back to chapter

Transcribe

Pega una audio URL pública (mp3, wav, m4a) y obtén la transcripción. Speech to

Showcase — Transcribe

Pega una audio URL pública (mp3, wav, m4a) y obtén la transcripción. Speech to text: el backend descarga los bytes y se los entrega al modelo de transcripción. Para OpenAI ese es el endpoint de transcripción dedicado; para Gemini es la misma llamada multimodal que vision, con una parte de audio.

Córrelo

bash bootstrap-secrets.sh              # reads ../../../../.env, writes secrets/
docker compose up --build              # default: PROVIDER=openai

Abre http://localhost:3000. Gemini: PROVIDER=gemini docker compose up --build.

Qué hay aquí

  • backend/ai_openai.pyaudio.transcriptions.create sobre los bytes descargados.
  • backend/ai_gemini.py — una llamada multimodal con una parte de audio.
  • frontend/app/page.tsx — caja de URL + transcripción.

Detenlo

docker compose down

Ejecútalo en tu máquina

Descarga el proyecto como ZIP y córrelo con Docker. Levanta un backend FastAPI y un frontend Next.js en localhost:3000.

Descargar transcribe.zip

unzip transcribe.zip
cd transcribe
bash bootstrap-secrets.sh   # one-time: pulls API keys into ./secrets
docker compose up --build   # default provider: openai
# or:  PROVIDER=gemini docker compose up --build

Escribe algo, elige un proveedor y ejecuta el mismo código de Código contra la API real. Requiere iniciar sesión.


  

Los mismos módulos que ejecuta el botón Run. El proyecto completo (frontend, Dockerfile, compose) está en el ZIP, pestaña README.

backend/ai_openai.py

"""Showcase 1 (OpenAI): speech to text from a URL.

Paste a public audio URL (mp3, wav, m4a) and get the transcript. We download the
bytes and hand them to the transcription model with a filename so it knows the
format.
"""
import urllib.request

from openai import OpenAI

_client = OpenAI()

_MODEL = "gpt-4o-mini-transcribe"


def run(audio_url: str) -> str:
    url = audio_url.strip()
    if not url.startswith("http"):
        return "Paste a public audio URL (http/https): mp3, wav, or m4a."
    data = urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})).read()
    name = url.split("/")[-1].split("?")[0] or "audio.mp3"
    return _client.audio.transcriptions.create(model=_MODEL, file=(name, data)).text

backend/ai_gemini.py

"""Showcase 1 (Gemini): speech to text from a URL.

Transcription is the multimodal call from week 10 with an audio part instead of
an image part.
"""
import os
import urllib.request

from google import genai
from google.genai import types

_client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])

_MODEL = "gemini-3.1-flash-lite"

_MIME = {"mp3": "audio/mpeg", "wav": "audio/wav", "m4a": "audio/mp4", "ogg": "audio/ogg", "flac": "audio/flac"}


def _mime(url: str) -> str:
    ext = url.lower().split("?")[0].rsplit(".", 1)[-1]
    return _MIME.get(ext, "audio/mpeg")


def run(audio_url: str) -> str:
    url = audio_url.strip()
    if not url.startswith("http"):
        return "Paste a public audio URL (http/https): mp3, wav, or m4a."
    data = urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})).read()
    response = _client.models.generate_content(
        model=_MODEL,
        contents=[
            types.Part.from_bytes(data=data, mime_type=_mime(url)),
            "Transcribe this audio verbatim. Output only the transcript.",
        ],
    )
    return response.text or ""

Archivos del proyecto

  • .gitignore
  • README.es.md
  • README.md
  • backend/Dockerfile
  • backend/ai_gemini.py
  • backend/ai_openai.py
  • backend/main.py
  • backend/requirements.txt
  • bootstrap-secrets.sh
  • docker-compose.yml
  • frontend/Dockerfile
  • frontend/app/layout.tsx
  • frontend/app/page.tsx
  • frontend/next.config.ts
  • frontend/package.json
  • frontend/tsconfig.json