Você lembra de uma frase de uma reunião, aula ou entrevista, mas não sabe em que minuto ela apareceu. Procurar manualmente em horas de vídeo é uma tarefa ruim para pessoas e desnecessária para computadores.

Vamos construir um fluxo simples: ele extrai o áudio de um vídeo, envia o arquivo para um modelo de voz da HiNow, salva a transcrição em um arquivo .txt e permite procurar palavras com grep. O resultado final não é uma plataforma completa. É melhor para aprender: uma pasta de vídeos vira uma pasta de textos pesquisáveis, executada com Node.js 18 ou mais novo e uma ferramenta de sistema para manipular áudio.

A primeira versão funciona com um vídeo curto. Depois, veremos como dividir gravações longas, validar o resultado e lidar com o erro mais traiçoeiro desse tipo de automação: áudio sem fala que ainda produz texto.

O ganho aparece antes da primeira linha de código

Suponha que localizar um trecho assistindo a um vídeo leve, em média, metade da duração dele. Em 10 horas de gravação, achar uma frase custa cerca de 5 horas de atenção. Com o texto no disco, uma busca por palavra pode ser feita em segundos pelo terminal.

Essa conta é uma premissa para calibrar a ordem de grandeza, não uma medição universal. O ponto permanece: transcrever muda o formato do problema. Você deixa de procurar no tempo e passa a procurar no conteúdo.

A transcrição não precisa ser perfeita para cumprir esse papel. Nomes próprios, siglas e termos técnicos saem errados com alguma frequência. Por isso, o arquivo serve para encontrar e revisar. Se a frase for virar publicação, ata oficial ou legenda final, alguém ainda precisa conferir o áudio.

Prepare um vídeo curto e extraia apenas o que a API precisa

Fluido denso e transparente sendo filtrado por um canal estreito, simbolizando a preparação de dados para processamento.
Filtrar o essencial antes de enviar para o modelo.

Instale o ffmpeg no sistema. Ele não é um pacote do projeto, mas a ferramenta que converte a trilha do vídeo para um formato previsível: áudio mono, com taxa de amostragem de 16 kHz.

ffmpeg -i aula.mp4 -ar 16000 -ac 1 audio.mp3

A conversão separa duas responsabilidades. O ffmpeg entende contêineres de vídeo e codecs; o modelo de voz recebe um arquivo de áudio. Mono reduz canais desnecessários e uma taxa fixa torna o fluxo mais fácil de repetir.

Agora crie transcribe.mjs:

import { readFile, writeFile } from "node:fs/promises";

const audioPath = process.argv[2];
const outputPath = process.argv[3] ?? "transcription.txt";

if (!audioPath) {
  throw new Error("Usage: node transcribe.mjs <audio-file> [output-file]");
}

if (!process.env.HINOW_API_KEY) {
  throw new Error("HINOW_API_KEY is not set");
}

const audio = await readFile(audioPath);
const form = new FormData();
form.append("model", "hinow/hivox");
form.append("language", "pt");
form.append("file", new Blob([audio]), audioPath.split("/").pop());

const response = await fetch("https://api.hinow.ai/v1/audio/transcriptions", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.HINOW_API_KEY
  },
  body: form
});

if (!response.ok) {
  throw new Error(await response.text());
}

const data = await response.json();
await writeFile(outputPath, data.text + "\n", "utf8");
console.log(`Saved ${outputPath} (${data.duration}s)`);

O detalhe que costuma quebrar o primeiro teste é language. Esse campo é obrigatório e recebe o idioma falado, não o idioma para o qual o áudio deve ser traduzido. Para português, use pt. A API também aceita a forma regional pt-BR, mas a reduz para pt.

O FormData é intencional. Essa rota recebe multipart/form-data, porque o corpo carrega o arquivo junto com os campos do pedido. No Node 18 ou mais novo, FormData, Blob e fetch já existem. Não precisamos adicionar um pacote só para montar o envio.

Execute assim:

export HINOW_API_KEY="sua-chave"
node transcribe.mjs audio.mp3 aula.txt

O JSON retornado contém duration, em segundos, e text, com a transcrição completa. O programa guarda apenas o texto porque é ele que alimentará a busca. Durante a depuração, vale imprimir o objeto inteiro para conferir o formato recebido.

Transforme a pasta de textos em uma busca

Com aula.txt pronto, procure uma palavra que você espera encontrar no conteúdo, como áudio:

grep -in "áudio" aula.txt

O -i ignora maiúsculas e minúsculas. O -n mostra a linha encontrada. Como a transcrição ainda não tem marcações de tempo, o resultado localiza o trecho no texto, mas não informa diretamente o minuto do vídeo.

Para pesquisar vários arquivos, coloque as transcrições em uma pasta e rode:

grep -Rin "áudio" transcricoes/

Esse índice simples já resolve uma classe inteira de problemas: rever decisões de reuniões, encontrar uma explicação em aulas gravadas e localizar menções a um conceito em entrevistas. O ganho vem da composição de ferramentas pequenas, não de um sistema sofisticado.

Vídeos longos pedem blocos, não uma chamada gigante

Uma gravação longa deve ser dividida em partes. Isso reduz o risco de uma chamada falhar depois de muito tempo, facilita repetir apenas o trecho com erro e permite processar blocos separadamente.

O tamanho do bloco é uma escolha de projeto. Você pode defini-lo de acordo com a duração dos vídeos, a memória disponível e a facilidade de repetir chamadas. O número de arquivos depende da duração escolhida para cada bloco.

Defina a duração desejada em uma variável de shell e use-a no comando:

BLOCK_SECONDS=600
mkdir -p chunks
ffmpeg -i aula.mp4 -f segment -segment_time "$BLOCK_SECONDS" -ar 16000 -ac 1 chunks/chunk-%03d.mp3

O valor de BLOCK_SECONDS é apenas uma escolha de exemplo. A variável deixa explícito o ponto que você deve ajustar, em vez de esconder a decisão dentro do comando.

Depois, percorra os arquivos em ordem e envie cada um para a mesma rota. O algoritmo é simples: listar os blocos, ordenar pelo nome, transcrever um por vez e concatenar os textos. Manter a ordem dos nomes é importante porque o modelo não sabe onde aquele bloco se encaixa na gravação original.

Uma implementação de produção deve registrar o nome do bloco, o duration retornado e eventuais erros. Se um bloco falhar, você não precisa pagar ou esperar novamente pelos anteriores.

Valide antes de confiar no arquivo

A primeira verificação compara a duração real do áudio com o campo duration devolvido pela API. Uma diferença grande indica conversão incompleta, arquivo errado ou bloco perdido.

A segunda é humana e pequena: escolha um trecho aleatório, escute o áudio e compare com o texto. Não leia apenas o começo. Erros de nomes, números, siglas e fala sobreposta aparecem em pontos diferentes da gravação.

Existe ainda um caso que merece tratamento explícito. Em um teste real específico, um tom puro de 440 Hz produziu um caractere solto em vez de texto vazio. Isso mostra que uma resposta não vazia não prova a existência de fala. Música, silêncio e ruído podem gerar texto espúrio.

Uma regra prática é descartar transcrições muito curtas em relação à duração do bloco e, em produção, cortar silêncio antes do envio. Essa regra é um filtro, não uma prova: áudio curto com fala real também pode ser válido.

O próximo passo é recuperar significado, não só palavras

Depois que a busca literal funcionar, você pode pedir a um modelo de linguagem que gere resumo e capítulos a partir dos arquivos .txt. Essa etapa deve vir depois da transcrição, porque cada chamada adicional aumenta tempo, custo e superfície para erro.

Se o fluxo processar vários blocos e depois fizer uma chamada para montar o resultado final, haverá uma chamada por bloco mais uma chamada final. O tempo total varia conforme o número de blocos, o tamanho dos arquivos, a latência da rede e o processamento do serviço.

Busca semântica é outra evolução. Em vez de procurar a palavra exata, você transforma trechos em embeddings e compara a proximidade entre vetores. Isso encontra uma explicação sobre “atenção” mesmo quando o áudio usou outra expressão. Mas a busca literal continua sendo a camada mais barata, transparente e fácil de validar.

Comece com um vídeo curto, confira o texto contra o áudio e só então automatize a pasta inteira. Nesse estágio, as horas de vídeo passam a funcionar como material pesquisável pelo computador. Quando o arquivo carregar também duração, bloco de origem e, depois, marcações de tempo, você terá uma base sólida para navegar pelo conteúdo sem assistir a tudo de novo.