Início → Blog → Como transcrever uma gravação que não cabe em uma requisição
Como transcrever uma gravação que não cabe em uma requisição
Uma gravação de conferência de quatro horas, um despejo do gravador do dia inteiro, um webinar com captura de tela — nada disso cabe em uma requisição. O trabalho se divide em três passos: comprimir, cortar nas pausas, juntar o texto de volta. Segue a receita com código.
Comprima antes de cortar
Tente a compressão primeiro; muitas vezes basta. Uma hora de fala em opus tem cerca de 11 MB, então uma gravação de duas horas cabe inteira no limite:
ffmpeg -i conference.wav -vn -ac 1 -ar 16000 -c:a libopus -b:a 24k conference.ogg
Dividir só faz sentido quando, mesmo comprimido, o arquivo continua grande, ou quando você quer processar em paralelo por velocidade.
Onde cortar sem estragar
Cortar em intervalos fixos é fácil e cedo ou tarde parte uma palavra, deixando lixo na emenda. Cortar no silêncio é mais seguro. Primeiro encontre as pausas:
ffmpeg -i long.ogg -af silencedetect=noise=-35dB:d=1 -f null - 2>&1 | grep silence_end
Depois corte na pausa mais próxima do tamanho desejado:
ffmpeg -i long.ogg -ss 0 -to 912.4 -c copy part001.ogg
Um meio-termo prático são pedaços de 10 a 15 minutos: cômodos para enviar em paralelo e com prejuízo mínimo numa emenda infeliz.
Processar os pedaços em paralelo
Os pedaços são independentes, então envie de uma vez e mantenha a ordem pelo nome do arquivo:
import concurrent.futures as cf, pathlib
from openai import OpenAI
client = OpenAI(base_url="https://voicesscribe.com/v1", api_key="sua chave")
def one(path):
with path.open("rb") as f:
return path.name, client.audio.transcriptions.create(model="whisper-1", file=f).text
parts = sorted(pathlib.Path(".").glob("part*.ogg"))
with cf.ThreadPoolExecutor(max_workers=4) as pool:
result = dict(pool.map(one, parts))
full = "\n".join(result[p.name] for p in parts)
pathlib.Path("conference.txt").write_text(full, encoding="utf-8")
Ajuste o número de trabalhadores ao limite de requisições por segundo do seu plano: passar disso rende 429 e retrabalho.
Tempos contínuos
Se você precisa de navegação e não de texto puro, peça segmentos e some o deslocamento de cada pedaço:
offset = 0.0
for path in parts:
with path.open("rb") as f:
r = client.audio.transcriptions.create(
model="whisper-1", file=f, response_format="verbose_json")
for seg in r.segments:
print(round(seg["start"] + offset, 1), seg["text"].strip())
offset += r.duration
Assim as marcações continuam alinhadas com a gravação original e podem controlar um player.
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
Qual o limite de tamanho do arquivo?
25 MB por requisição. Em opus isso dá cerca de duas horas de fala, então geralmente só comprimir já dispensa a divisão.
O que significa o erro 413?
O arquivo passou do tamanho permitido. Comprima para opus ou mp3 de bitrate baixo, ou divida em partes.
Perde-se sentido nas emendas?
Não, se você cortar no silêncio. Cortes em intervalo fixo podem engolir uma palavra na emenda, por isso procurar as pausas compensa.
Os pedaços podem ser processados juntos?
Podem, são independentes. A única restrição é o limite de requisições por segundo do seu plano.
Leitura relacionada
- Preparando áudio para transcrição: receitas de ffmpeg — Comandos ffmpeg prontos para reconhecimento de fala: extrair áudio de vídeo, converter para mono, cortar silêncio, dividir nas pausas e separar canais.
- 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.
- Erros da API de transcrição e o que eles realmente significam — Explicação dos códigos de status da API: por que aparecem 401, 400, 413, 429 e 502, como corrigir cada um e quais falhas vale a pena repetir.