Início → Blog → 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
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:
| Formato | O que você recebe | Use quando |
|---|---|---|
json | Objeto com .text | Padrão; você só quer as palavras |
verbose_json | Segmentos, tempos, idioma detectado | Marcações, capítulos, controle de qualidade |
srt / vtt | Arquivo de legenda pronto como string | Legendas para vídeo |
text | String pura, sem envelope | Encadear 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.mp3Deixando 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
- Ler o arquivo inteiro na memória para passá-lo como bytes. Passe o objeto de arquivo — o SDK envia em fluxo.
- Repetir um resultado vazio. String vazia significa que não houve fala, não que algo falhou. Repetir só gasta minutos.
- Manter o timeout padrão em arquivos longos. O padrão do cliente serve a trechos curtos; aumente para gravações de uma hora.
- Fazer upsample de áudio de telefone de 8 kHz para 44 kHz esperando mais precisão. Isso acrescenta bytes, não informação.
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átisPerguntas 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
- Voz para texto em Node.js: código pronto e as armadilhas de sempre — Como transcrever áudio a partir do Node.js: o SDK oficial, streams e FormData, uploads no Express, timeouts e novas tentativas — com código pronto para colar.
- Como montar um pipeline de transcrição para um acervo de áudio — Transcrever milhares de gravações sem perder nenhuma: fila de trabalho, concorrência, novas tentativas, retomada após uma queda e controle do valor da fatura.
- Como melhorar a precisão da transcrição: oito ajustes práticos — Oito mudanças que realmente movem a qualidade da transcrição: preparo do áudio, idioma explícito, o parâmetro prompt, corte em pausas, formatos e como medir o erro.