TAS — Texto e Fala, em Ambos os Sentidos (API Speakee)
Um único script faz ambos os sentidos:
- Texto → Fala (TTS): Mais de 40 idiomas, mais de 100 vozes, UID de voz personalizado, chunking de texto longo, modo de conversa com múltiplas vozes, junção com ffmpeg, verificação de qualidade de áudio.
- Áudio → Texto (STT): Transcreva qualquer arquivo de áudio/vídeo para texto, com timestamps de palavras e legendas SRT/WebVTT, e chunking automático para gravações longas.
Tudo é feito pelo script incluído — nunca o reimplemente inline e NUNCA instale nada (sem whisper, sem torch, sem faster-whisper, sem pip):
<diretório base da skill>/scripts/tas.py
Locais típicos de instalação:
~/.config/opencode/skills/tas/scripts/tas.py (opencode),
~/.claude/skills/tas/scripts/tas.py (Claude Code) e
~/.agents/skills/tas/scripts/tas.py (a CLI skills, npx skills add).
A habilidade se chama tas — carregue-a com o nome tas, nunca tts.
Regras inegociáveis (aplicam-se a TODA requisição)
- Use o script incluído. Sem trechos curl/python ad-hoc para TTS ou STT.
- NUNCA instale nada. Não execute
pip install faster-whisper,pip install whisper,pip install torchou baixe qualquer modelo. O script faz STT inteiramente através da API Speakee com a biblioteca padrão do Python — sem modelo local, sem download local, sem pip. - Verifique antes de entregar.
ttseconversationexecutam verificação de qualidade de áudio automaticamente; umQA: FAILdeve ser corrigido, nunca enviado. - Relate o resultado: caminho final, duração, tamanho e status QA (TTS); caminho final do SRT/VTT/texto e contagem de cues (STT).
- Sempre faça o pré-voo. Idioma, modelo e voz são validados antes de qualquer requisição; nunca envie uma voz adivinhada.
- Mantenha o cache ativado a menos que o usuário solicite o contrário. Isso torna as reexecuções rápidas e retoma conversas com falha.
- Nunca adivinhe um nome de voz. Resolva com
voices/suggest, ou passe o UUID. - Respeite a API gratuita: padrão
--workers 4; reduza-o em caso de HTTP 429. - Deixe o script normalizar o texto. Markdown, URLs, HTML e emojis são
removidos por padrão; use
--rawapenas quando o usuário quiser texto literal. - Nunca pré-divida texto longo. O script divide nos limites de sentenças e mescla automaticamente.
- Sempre passe
-l <código>para STT quando o idioma for conhecido. A detecção automática é não confiável (Whisper confunde bengali/gujarati);-l bné obrigatório para bengali correto. - Use
--jsonquando outra ferramenta ou script consumir o resultado.
Comandos
| Comando | Propósito |
|---|---|
tts | Sintetizar um bloco de texto (TTS) |
uid | Sintetizar com um UID de voz personalizado (language=uid) |
conversation | Diálogo com múltiplos falantes → um MP3 costurado e verificado |
stt | Transcrever um arquivo de áudio/vídeo → texto (+ SRT/VTT opcional) |
transcribe | Alias para stt |
subtitle | Transcrever e escrever um SRT |
verify | Executar verificação de qualidade de áudio em qualquer arquivo |
voices -l <código> | Listar vozes para um idioma |
suggest -l <código> | Listar vozes com recomendações marcadas |
presets | Listar predefinições de voz |
languages | Listar idiomas suportados |
models | Listar modelos (sonic-3.5 padrão) |
cache-clear | Excluir o cache de síntese |
Fluxo de Trabalho A — Texto para Fala (TTS)
Passo 1 — Escopo
Identifique: idioma (ou deixe a detecção automática funcionar), tom (notícias / história / assistente /
audiobook), um ou múltiplos falantes, caminho de saída desejado e se legendas
(--srt) ou metadados (--title/--artist) são necessários.
Passo 2 — Escolha idioma e voz
python3 "$S" languages # 43 códigos
python3 "$S" suggest -l bn # vozes recomendadas primeiro
python3 "$S" presets # conjuntos de vozes curados
Se o usuário tiver um UID de voz personalizado, use o modo uid. Caso contrário, prefira uma predefinição
ou uma voz recomendada em vez da padrão.
Passo 3 — Sintetize
Falante único:
python3 "$S" tts "Seu texto" -l bn -o out.mp3
python3 "$S" tts --text-file artigo.md -l en --preset news -o artigo.mp3
Diálogo:
python3 "$S" conversation dialogo.txt -l bn \
--map "Pessoa=Nayem,AI=Pooja - Assistente Diário" \
--loudnorm --srt dialogo.srt -o dialogo.mp3
Use --dry-run primeiro para execuções longas ou caras.
Passo 4 — Verifique
A verificação de qualidade é executada automaticamente. Para reverificar qualquer arquivo:
python3 "$S" verify out.mp3
Verificações: decodificação, duração, sonoridade integrada (ebur128), pico real/clipping, e silêncio inicial/final/interno. Código de saída 5 significa FALHA.
Passo 5 — Entregue
Relate:
out.mp3 — 2.8s, 0.04 MB, QA PASS (-18.9 LUFS, pico -4.2 dBFS)
Não cole JSON bruto a menos que solicitado.
Passo 6 — Reutilize
Reexecuções usam o cache (~/.cache/speakee-tas). Use --force para regenerar,
cache-clear para limpar.
Fluxo de Trabalho B — Fala para Texto (STT)
Use isso quando o usuário tiver um arquivo de áudio ou vídeo e quiser uma transcrição,
legendas, legendas ocultas ou um SRT. Não instale Whisper — o script incluído
chama o endpoint /api/stt da Speakee diretamente.
Passo 1 — Confirme o arquivo
python3 "$S" verify /caminho/para/audio.mp3 # opcional: confirma que decodifica
ls -la /caminho/para/audio.mp3
Passo 2 — Escolha o idioma
# Detecção automática (não confiável — Whisper confunde bengali/gujarati):
python3 "$S" stt audio.mp3
# SEMPRE prefira idioma explícito quando conhecido:
python3 "$S" stt audio.mp3 -l bn
Importante: passe -l <código> para a escrita correta. Para bengali use
-l bn; a detecção automática retorna gujarati para áudio bengali. Avisos de
baixa confiança (< 0.5) significam que o idioma detectado provavelmente está errado.
Passo 3 — Transcreva + crie legendas
# Escreva SRT + VTT próximo à entrada e salve a transcrição:
python3 "$S" stt audio.mp3 -l bn \
--srt --srt-path audio.srt --vtt --vtt-path audio.vtt \
-o audio.txt
# Atalho: apenas o SRT (comando subtitle):
python3 "$S" subtitle audio.mp3 -l bn -o audio.srt
# JSON legível por máquina (para outras ferramentas):
python3 "$S" stt audio.mp3 -l bn --json -o resultado.json
# Gravações longas: chunking automático ~120s; force chunks menores ou um upload:
python3 "$S" stt audio.mp3 -l bn --chunk-seconds 60
python3 "$S" stt audio.mp3 -l bn --no-chunk # apenas se < ~3.5 MB
Passo 4 — Entregue
Relate:
audio.srt — 111 cues (8.05 min, bengali)
audio.txt — transcrição salva
Flags do STT: --srt, --srt-path, --vtt, --vtt-path, --no-word-timestamps
(mais rápido, temporização estimada), --chunk-seconds, --no-chunk, --workers,
--max-chars, --max-line-seconds.
Modo de conversa (TTS)
Formato do script, uma fala por linha:
O show começa. <- sem prefixo "Falante:" -> voz do narrador
Pessoa: Mano, quanto é 2+2?
AI: Sua pergunta foi recebida.
- Rótulos de falante são tokens curtos antes de
:(≤16 caracteres, sem espaços). - Linhas sem prefixo
Falante:são do narrador/comentarista. O narrador é mapeado com a chave especialnarrator, então uma 3ª voz distinta é--map "narrator=VozC,Pessoa=VozA,AI=VozB". --map "falante=voz"aceita um nome de voz (difuso) ou UUID.- Sem
--map, vozes distintas são atribuídas automaticamente. - As vozes devem ser distintas. Se dois falantes resolverem para a mesma voz, o
script imprime um
WARNING; mapeie cada falante para uma voz diferente. Sempre dê ao AI e ao humano vozes diferentes (e uma 3ª voz para o narrador quando uma linha de comentarista/narrador estiver presente). --silence 0.35pausa entre falas;--loudnormnormaliza para −16 LUFS.--manifest ARQUIVOregistra cada segmento;--srt ARQUIVOescreve legendas.--no-stitchmantém arquivos de segmento individuais em vez de um MP3.--workerscontrola requisições paralelas (padrão 4).
Opções (mais usadas)
| Flag | Padrão | Significado |
|---|---|---|
-l, --language | auto-detect | Código ISO ou uid |
-m, --model | sonic-3.5 | sonic-3.5 / sonic-3 / sonic-turbo / sonic-2 |
-v, --voice_id | predefinição/padrão | Nome da voz ou UUID |
-o, --out | auto | Arquivo/diretório de saída (--no-stitch) |
-s, --speed | 1.2 | 0.5–2.0 |
--preset | — | news, story, assistant, audiobook |
--chunk-limit | 1200 | Caracteres por requisição |
--retries | 4 | Tentativas com backoff exponencial |
--workers | 4 | Requisições paralelas |
--no-cache / --force | desligado | Ignorar cache / regenerar |
--no-verify | desligado | Pular verificação automática de qualidade (não recomendado) |
--dry-run | desligado | Imprimir o plano, não fazer requisições |
--json | desligado | Saída legível por máquina |
Opções STT
| Flag | Padrão | Significado |
|---|---|---|
-l, --language | auto | Código ISO (use bn para bengali) |
--chunk-seconds | 120 | Segundos de áudio por upload |
--no-chunk | desligado | Uma requisição (máx ~3.5 MB) |
--workers | 2 | Uploads paralelos |
--srt / --srt-path | desligado | Escrever um SRT |
--vtt / --vtt-path | desligado | Escrever um WebVTT |
--no-word-timestamps | desligado | Mais rápido; temporização de legenda é estimada |
--max-chars | 42 | Máximo de caracteres por cue |
--max-line-seconds | 6.0 | Máximo de segundos por cue |
--timeout / --retries | 300 / 3 | Timeout / tentativas por requisição |
Cache e segurança
- Segmentos são armazenados em cache por hash de conteúdo em
~/.cache/speakee-tas; reexecuções e tentativas são retomadas automaticamente. - Arquivos temporários de concatenação são sempre removidos; diretórios temporários
--no-cachesão limpos na saída. - Respostas são validadas (
Content-Type: audio/*+ cabeçalho MP3), então JSON de erro nunca é salvo como áudio. - HTTP 429 respeita
Retry-After; 5xx/timeouts tentam novamente com backoff; 4xx permanentes falham imediatamente com a mensagem do servidor. - STT é executado inteiramente em processo com a biblioteca padrão do Python — sem instalação de rede, sem download de modelo, sem pip.
- Códigos de saída:
0ok,1erro,2uso,3validação,4rede/API,5verificação de qualidade de áudio falhou.
Arquivos de referência
references/api.md— endpoints, payload, validação, tentativas, cache.references/voices.md— catálogo de idiomas/vozes, modo UID, predefinições.references/troubleshooting.md— sintomas, correções, modos de falha comuns.assets/presets.json— predefinições de voz curadas (edite para adicionar as suas).