0Pricing
AI Agents · Lección

Conversión de voz a texto con Whisper y Deepgram

Transcripción en tiempo real y por lotes, detección de idioma y puntuación.

Conversión de voz a texto con Whisper y Deepgram es una lección gratuita de AI Agents en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Agents, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Agents incluye 4 lecciones en total.

Conversión de voz a texto en agentes de voz

Un agente de voz debe convertir el audio hablado en texto antes de que el LLM pueda procesarlo. Este paso se denomina Speech-to-Text (STT) o Automatic Speech Recognition (ASR).

Hay dos opciones destacadas: OpenAI Whisper (basada en archivos y por lotes) y Deepgram (streaming en tiempo real, con diarización de hablantes y marcas de tiempo por palabra).

OpenAI Whisper: transcripción básica

Whisper, mediante la API de OpenAI, transcribe archivos de audio. Formatos compatibles: mp3, mp4, wav, webm, m4a y flac. Tamaño máximo del archivo: 25 MB.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def transcribe_file(audio_path, language=None):
    with open(audio_path, 'rb') as audio_file:
        params = {
            'model': 'whisper-1',
            'file': audio_file,
            'response_format': 'json'  # or 'text', 'srt', 'vtt', 'verbose_json'
        }
        if language:
            params['language'] = language  # e.g., 'en', 'fr', 'de'

        transcript = client.audio.transcriptions.create(**params)

    return transcript.text

# Basic usage
text = transcribe_file('meeting_recording.mp3')
print('Transcribed:', text[:200])

Whisper con marcas de tiempo por palabra

Utilice response_format='verbose_json' para obtener marcas de tiempo de cada palabra y segmento. Esto resulta útil para encontrar momentos específicos en las grabaciones, resaltar texto al estilo del karaoke y sincronizar las transcripciones con la reproducción de audio.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def transcribe_with_timestamps(audio_path):
    with open(audio_path, 'rb') as f:
        result = client.audio.transcriptions.create(
            model='whisper-1',
            file=f,
            response_format='verbose_json',
            timestamp_granularities=['word', 'segment']  # get both word and segment times
        )

    segments = []
    for seg in result.segments:
        segments.append({
            'start': seg.start,
            'end':   seg.end,
            'text':  seg.text
        })

    words = []
    if hasattr(result, 'words'):
        for word in result.words:
            words.append({'word': word.word, 'start': word.start, 'end': word.end})

    return {'text': result.text, 'segments': segments, 'words': words}

SDK de Deepgram: streaming asíncrono

Deepgram está optimizado para la transcripción en streaming en tiempo real. El audio se envía en fragmentos a medida que se graba; las transcripciones parciales se devuelven antes de que el hablante termine una oración.

Instálelo con pip install deepgram-sdk.

import asyncio
import os
from deepgram import DeepgramClient, PrerecordedOptions

client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

async def transcribe_with_deepgram(audio_path):
    with open(audio_path, 'rb') as f:
        audio_data = f.read()

    options = PrerecordedOptions(
        model='nova-2',            # Deepgram's best accuracy model
        language='en',
        smart_format=True,         # auto-add punctuation and formatting
        utterances=True,           # segment by speaker turns
        punctuate=True,
        diarize=True               # speaker identification
    )

    response = await client.listen.asyncrest.v('1').transcribe_file(
        {'buffer': audio_data},
        options
    )

    return response.results.channels[0].alternatives[0].transcript

Diarización de hablantes

La diarización identifica quién habla y cuándo, etiquetando los segmentos como Speaker 0, Speaker 1, etc. Es fundamental para las transcripciones de reuniones y las conversaciones entre varias personas.

async def transcribe_with_diarization(audio_path):
    from deepgram import DeepgramClient, PrerecordedOptions
    import os

    dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

    options = PrerecordedOptions(
        model='nova-2',
        diarize=True,
        utterances=True,
        smart_format=True
    )

    with open(audio_path, 'rb') as f:
        audio_data = f.read()

    response = await dg_client.listen.asyncrest.v('1').transcribe_file(
        {'buffer': audio_data}, options
    )

    utterances = []
    for utt in response.results.utterances:
        utterances.append({
            'speaker': f'Speaker {utt.speaker}',
            'start':   round(utt.start, 2),
            'end':     round(utt.end, 2),
            'text':    utt.transcript
        })

    return utterances

# Output:
# [{'speaker': 'Speaker 0', 'start': 0.0, 'end': 3.2, 'text': 'Hello everyone.'},
#  {'speaker': 'Speaker 1', 'start': 3.5, 'end': 6.1, 'text': 'Good morning!'}]

Detección del idioma

Cuando se desconoce el idioma del usuario, tanto Whisper como Deepgram pueden detectarlo automáticamente a partir del habla. Whisper detecta el idioma usando los primeros 30 segundos de audio.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

def detect_language(audio_path):
    with open(audio_path, 'rb') as f:
        # Use translations endpoint to get verbose JSON with language detection
        result = client.audio.transcriptions.create(
            model='whisper-1',
            file=f,
            response_format='verbose_json'
        )
    return {
        'detected_language': result.language,
        'text': result.text
    }

result = detect_language('user_audio.wav')
print(f"Language: {result['detected_language']}")
print(f"Text: {result['text'][:100]}")

# Deepgram: set language='auto' in options
from deepgram import PrerecordedOptions
options = PrerecordedOptions(model='nova-2', language='auto', detect_language=True)

División de archivos de audio largos en fragmentos

El límite de 25 MB de Whisper implica que las grabaciones largas, como reuniones de una hora, deben dividirse en fragmentos. Divida el audio por silencios mediante pydub, transcriba cada fragmento y concaténelos.

Instálelo con pip install pydub. Requiere ffmpeg.

from pydub import AudioSegment
from pydub.silence import split_on_silence
import io

def transcribe_long_audio(audio_path, chunk_length_ms=60000):
    audio = AudioSegment.from_file(audio_path)

    # Split on silence
    chunks = split_on_silence(
        audio,
        min_silence_len=1000,   # 1 second of silence
        silence_thresh=-40,     # dBFS
        keep_silence=500        # keep 500ms at each end
    )

    # If no silence splitting worked, use fixed-length chunks
    if len(chunks) <= 1:
        chunks = [
            audio[i:i + chunk_length_ms]
            for i in range(0, len(audio), chunk_length_ms)
        ]

    full_transcript = []
    for i, chunk in enumerate(chunks):
        print(f'Transcribing chunk {i+1}/{len(chunks)}')
        buf = io.BytesIO()
        chunk.export(buf, format='mp3')
        buf.seek(0)
        buf.name = f'chunk_{i}.mp3'
        result = client.audio.transcriptions.create(model='whisper-1', file=buf)
        full_transcript.append(result.text)

    return ' '.join(full_transcript)

Streaming en vivo con Deepgram

Para conversaciones de voz en tiempo real, utilice la API de streaming en vivo mediante WebSocket de Deepgram. Los fragmentos de audio se envían a medida que se graban; las transcripciones provisionales y finales llegan en cuestión de milisegundos.

import asyncio
import os
from deepgram import DeepgramClient, LiveTranscriptionEvents, LiveOptions

async def live_transcribe(on_transcript_callback):
    dg_client = DeepgramClient(os.getenv('DEEPGRAM_API_KEY'))

    connection = dg_client.listen.asynclive.v('1')

    async def on_message(self, result, **kwargs):
        sentence = result.channel.alternatives[0].transcript
        is_final = result.is_final
        if sentence:
            await on_transcript_callback(sentence, is_final)

    connection.on(LiveTranscriptionEvents.Transcript, on_message)

    options = LiveOptions(
        model='nova-2',
        language='en',
        smart_format=True,
        interim_results=True,  # get partial results before sentence ends
        endpointing=500        # ms of silence before finalizing
    )

    await connection.start(options)
    return connection  # caller sends audio chunks via connection.send(audio_chunk)

Gestión de errores y reintentos

Las API de transcripción de audio pueden fallar debido a problemas de red, formatos no compatibles o límites de solicitudes. Implemente reintentos con espera exponencial y valide el audio antes de enviarlo.

import time
import os

MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024  # 25MB
SUPPORTED_FORMATS = ('.mp3', '.mp4', '.wav', '.webm', '.m4a', '.flac', '.ogg')

def validate_audio_file(audio_path):
    if not os.path.exists(audio_path):
        raise FileNotFoundError(f'Audio file not found: {audio_path}')
    size = os.path.getsize(audio_path)
    if size > MAX_FILE_SIZE_BYTES:
        raise ValueError(f'File too large: {size / 1024 / 1024:.1f}MB (max 25MB)')
    ext = os.path.splitext(audio_path)[1].lower()
    if ext not in SUPPORTED_FORMATS:
        raise ValueError(f'Unsupported format: {ext}. Supported: {SUPPORTED_FORMATS}')

def transcribe_with_retry(audio_path, max_retries=3):
    validate_audio_file(audio_path)
    for attempt in range(max_retries):
        try:
            return transcribe_file(audio_path)
        except Exception as e:
            if attempt < max_retries - 1:
                wait = 2 ** attempt
                print(f'Retry {attempt + 1} after error: {e}. Waiting {wait}s')
                time.sleep(wait)
            else:
                raise

Cómo elegir entre Whisper y Deepgram

Ambas herramientas destacan en situaciones diferentes. Utilice esta matriz de decisión para elegir la opción adecuada para su agente de voz.

COMPARISON = '''
Whisper (OpenAI API):
  - Best for: batch transcription, podcast processing, meeting notes
  - Latency: file upload latency + ~1-5 seconds processing
  - Strengths: excellent multilingual, high accuracy, cheap
  - Word timestamps: yes (verbose_json)
  - Diarization: NO (must use separate tool)
  - Use when: accuracy > speed, offline processing

DeeGram:
  - Best for: real-time voice agents, call center transcription
  - Latency: <300ms for streaming, ~1s for file upload
  - Strengths: streaming, diarization, custom vocabulary
  - Word timestamps: yes, with confidence scores
  - Diarization: YES (built-in, up to 10 speakers)
  - Use when: speed > accuracy, real-time required

Rule of thumb:
  Agent voice conversation -> Deepgram live streaming
  Batch audio files -> Whisper API
  Meeting transcripts with speakers -> Deepgram with diarize=True
'''
print(COMPARISON)

Conversión de formatos de audio

Whisper y Deepgram son compatibles con formatos de audio habituales, pero el audio de los usuarios puede llegar en formatos poco comunes: ogg, opus, webm desde los navegadores o m4a desde iOS. Conviértalo a WAV o MP3 estándar antes de enviarlo a la API.

from pydub import AudioSegment
import os

SUPPORTED_FORMATS = {'.mp3', '.wav', '.flac', '.m4a', '.ogg', '.webm', '.opus'}

def convert_to_wav(input_path, output_path=None):
    ext = os.path.splitext(input_path)[1].lower()
    if ext not in SUPPORTED_FORMATS:
        raise ValueError(f'Unsupported audio format: {ext}')

    if output_path is None:
        output_path = input_path.rsplit('.', 1)[0] + '.wav'

    # pydub handles format detection automatically
    audio = AudioSegment.from_file(input_path)

    # Normalize to 16kHz mono (optimal for Whisper)
    audio = audio.set_frame_rate(16000).set_channels(1)

    audio.export(output_path, format='wav')
    print(f'Converted {input_path} -> {output_path} ({len(audio) / 1000:.1f}s)')
    return output_path

def ensure_compatible_audio(audio_path):
    ext = os.path.splitext(audio_path)[1].lower()
    if ext in {'.mp3', '.wav', '.m4a', '.flac'}:
        return audio_path  # already compatible
    return convert_to_wav(audio_path)

Comprobación de conocimientos

¿Qué es la diarización de hablantes en el contexto de la transcripción de voz a texto?

Resumen: conversión de voz a texto con Whisper y Deepgram

Whisper (API de OpenAI) es ideal para la transcripción por lotes: ofrece gran precisión y compatibilidad multilingüe, además de marcas de tiempo por palabra mediante verbose_json. Utilícelo para procesar archivos cuando la latencia no sea crítica.

Deepgram está diseñado para el streaming en tiempo real: ofrece transcripción en vivo mediante WebSocket, resultados provisionales, diarización de hablantes integrada y una latencia inferior a 300 ms. Utilícelo para agentes de voz interactivos. Ambas herramientas admiten la detección del idioma y, en producción, requieren lógica de reintentos y validación de archivos.

Preguntas frecuentes

¿La lección «Conversión de voz a texto con Whisper y Deepgram» es gratis?

Sí — el texto completo de «Conversión de voz a texto con Whisper y Deepgram» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Agents, actualiza a CoddyKit PRO. El curso de AI Agents incluye 4 lecciones en total.

¿Qué aprenderé en «Conversión de voz a texto con Whisper y Deepgram»?

Transcripción en tiempo real y por lotes, detección de idioma y puntuación. Practicas AI Agents con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar AI Agents?

No se requiere experiencia previa. AI Agents en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Conversión de voz a texto con Whisper y Deepgram»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de AI Agents?

Sí. Cada lección de AI Agents incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Conversión de voz a texto con Whisper y Deepgram
  2. Conversión de texto a voz en las respuestas de agentes
  3. Creación de un ciclo de conversación por voz
  4. Optimización de la latencia para agentes de voz
← Volver a AI Agents