InícioBlog → Voz para texto em Python: de um arquivo a um script que funciona

Voz para texto em Python: de um arquivo a um script que funciona

Publicado em 2026-08-18 · 6 min de leitura

Voz para texto em Python são quatro linhas de código. Todo o resto deste guia trata do que não é óbvio: qual formato de resposta pedir, o que fazer quando o arquivo é grande demais e por que o seu primeiro script será mais lento do que precisaria.

Instalação e primeira requisição

Uma dependência — o SDK oficial da OpenAI. A API é compatível no protocolo, então nenhum cliente especial é necessário:

pip install openai
from openai import OpenAI

client = OpenAI(base_url="https://voicesscribe.com/v1", api_key="sua chave")

with open("audio.mp3", "rb") as f:
    result = client.audio.transcriptions.create(model="whisper-1", file=f)

print(result.text)

É isso. Guarde a chave em uma variável de ambiente, não no código-fonte:

import os
client = OpenAI(base_url="https://voicesscribe.com/v1", api_key=os.environ["VS_KEY"])

Escolhendo o formato da resposta

O padrão devolve um objeto com o campo text. Outros três formatos importam:

FormatoO que você recebeUse quando
jsonObjeto com .textPadrão; você só quer as palavras
verbose_jsonSegmentos, tempos, idioma detectadoMarcações, capítulos, controle de qualidade
srt / vttArquivo de legenda pronto como stringLegendas para vídeo
textString pura, sem envelopeEncadear com outra ferramenta

Com verbose_json a resposta traz também o idioma detectado e sua probabilidade, o sinal de qualidade mais barato que existe:

r = client.audio.transcriptions.create(
    model="whisper-1", file=f, response_format="verbose_json",
)

for s in r.segments:
    print(f"[{s.start:6.1f}] {s.text.strip()}")

if r.language_probability < 0.6:
    print("gravação suspeita — vale conferir à mão")

Tratando erros do jeito certo

O SDK levanta exceções tipadas, então o tratamento é direto. A distinção que importa: alguns erros valem uma nova tentativa, outros falharão igual para sempre.

from openai import APIStatusError, APIConnectionError

try:
    r = client.audio.transcriptions.create(model="whisper-1", file=f)
except APIConnectionError:
    ...                      # rede — repetir faz sentido
except APIStatusError as e:
    if e.status_code == 401:
        raise RuntimeError("chave de API inválida")
    if e.status_code == 413:
        raise RuntimeError("arquivo acima de 25 MB — recodifique ou divida")
    if e.status_code == 429:
        ...                  # limite ou minutos esgotados — recue
    raise

Um 400 normalmente significa arquivo vazio ou corrompido. Verifique se ele abre em um player antes de culpar a API.

Arquivos maiores que 25 MB

O limite por requisição é de 25 MB. Dois caminhos, em ordem de preferência.

Recodifique primeiro. A maioria dos arquivos grandes demais é wav ou estéreo em bitrate alto. Mono a 16 kHz é o que o modelo usa internamente de qualquer forma:

ffmpeg -i entrada.wav -ac 1 -ar 16000 -b:a 48k saida.mp3

Isso transforma uma hora de áudio em cerca de 25 MB — a maioria dos arquivos deixa de precisar ser dividida.

Depois divida, se ainda for preciso. Corte em pausas e não em minutos fixos, para as frases ficarem inteiras:

ffmpeg -i longo.mp3 -f segment -segment_time 1800 -c copy parte%03d.mp3

Deixando mais rápido

O primeiro script que todo mundo escreve processa um arquivo por vez e passa quase todo o tempo esperando a rede. Transcrição é limitada por E/S, então threads resolvem:

from concurrent.futures import ThreadPoolExecutor

def transcrever(path):
    with open(path, "rb") as f:
        return client.audio.transcriptions.create(model="whisper-1", file=f).text

with ThreadPoolExecutor(max_workers=4) as pool:
    textos = list(pool.map(transcrever, caminhos))

Defina max_workers pelo limite de requisições por segundo do seu plano, não pelo número de núcleos. Passar do limite converte requisições bem-sucedidas em 429.

Melhorando a precisão no seu vocabulário

O parâmetro mais subutilizado é o prompt. Ele não aparece na saída — inclina o reconhecimento para as palavras que você lista:

r = client.audio.transcriptions.create(
    model="whisper-1", file=f,
    prompt="Produtos: Kestrel, Hawknest. Participantes: Duarte, Nogueira.",
    language="pt",
)

De vinte a quarenta termos que realmente aparecem no seu áudio funcionam bem; um parágrafo genérico não faz nada. Acrescentar language quando o áudio é de um idioma só elimina erros de detecção em trechos curtos.

Os erros que mais custam tempo

Teste com as suas próprias gravações. O cadastro leva um minuto e os minutos gratuitos bastam para avaliar a qualidade.

Obter uma chave de API grátis

Perguntas frequentes

Preciso de uma biblioteca Python específica?

Não, o pacote oficial openai funciona como está — a API é compatível no protocolo. Só a URL base e a chave diferem dos padrões da OpenAI.

Preciso preparar o formato do áudio no Python?

Nada em especial: ogg, opus, mp3, wav, m4a e webm são aceitos como estão. Converter para mp3 mono a 16 kHz serve apenas para ficar abaixo do limite de 25 MB por requisição.

Como obtenho marcações de tempo no Python?

Peça response_format=verbose_json — a resposta contém segmentos com início e fim, além do idioma detectado e sua probabilidade.

Dá para transcrever vários arquivos em paralelo?

Dá, com um ThreadPoolExecutor. A transcrição espera pela rede, então threads são a ferramenta certa; dimensione o pool abaixo do limite de requisições por segundo do seu plano.

O que fazer com arquivos acima de 25 MB?

Recodifique para mono a 16 kHz primeiro — só isso resolve a maioria dos casos. Se ainda for grande demais, divida em pausas e junte os resultados.

Leitura relacionada