Communitygithub.com

Perso Dubbing — envio lip-sync multi-idioma

Plugin Perso AI auto-dub: upload→split→translate→merge→MP4 com lip-sync. Multi-target num comando. README com GIFs. 38★.

O que é Perso Dubbing — envio lip-sync multi-idioma?

Video Localization passo 3: Perso 38★ dub lip-sync. Fresco vs VoxCPM 26/09 e IndexTTS 24/09.

Funciona com✓Claude Code✓Codex CLI✓Cursor✓Antigravity✓Gemini CLI
npx skills add perso-ai/perso-dubbing-plugin

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

/dubbing

Uma skill que dubla automaticamente vídeos através da API Perso AI Dubbing.

Regras principais (devem ser seguidas)

  • Apenas o worker vê a chave bruta. Nunca abra a chave com Ler, a ecoe ou a passe como argumento de linha de comandos. Os workers enviam-na apenas no cabeçalho XP-API-KEY.
  • Um comando = o trabalho completo. scripts/dubbing.mjs trata do carregamento, divisão, tradução, junção e gravação por si só. Nunca execute prepare_input.mjs ou probe_split.mjs antes dele — são ferramentas de depuração e o probe_split.mjs realiza um carregamento real (o vídeo seria carregado duas vezes).
  • Execute sempre dubbing.mjs em segundo plano. Os trabalhos demoram minutos a horas; um timeout da shell em primeiro plano mata a execução a meio.
  • Idiomas não especificados → fonte auto, destino en.
  • Vários idiomas num único comando (--target en,zh,ja) — o carregamento/divisão acontece uma vez e é reutilizado por idioma. Nunca execute uma vez por idioma (recarrega a fonte de cada vez).
  • Transmita o progresso fielmente. Mostre as linhas [progress] do stdout do worker no chat, na íntegra ou resumidas — e não anuncie passos que não apareceram (divisão/junção existem apenas para vídeos acima do limite). Os registos de detalhe indentados no stderr não precisam de ser transmitidos.
  • Mantenha o utilizador informado enquanto corre. Dublagem, lip-sync e separação de áudio imprimem todos um batimento cardíaco [status] (fase + contagens de itens, ex: ja 4/6 · en 1/6 ou separating — file 2/5, com uma dica next check ~Nm), e cada item concluído é transmitido como uma linha [progress]. Verifique a saída em segundo plano cerca de 3 minutos após o lançamento e depois no intervalo sugerido (10 minutos para média ≤10 min, 30 min para mais longo): transmita qualquer nova linha [progress] imediatamente; caso contrário, publique a linha [status] mais recente como uma atualização de uma linha. Nunca invente percentagens, tempo decorrido ou ETAs — transmita apenas o que as linhas dizem. Paragens que necessitam do utilizador ([space-select], [split-confirm], [free-limit], [resume-check], [credit-check], créditos insuficientes, conclusão) terminam o processo, por isso são apresentadas sem necessidade de sondagem.
  • Nomeie o seu runtime para telemetria (silencioso). Adicione --host <claude-code|codex|cursor|antigravity|gemini> ao comando do worker, nomeando o agente que está a executar, se conseguir identificá-lo. Serve apenas para marcar a telemetria de uso — nunca o mostre ao utilizador nem lhe pergunte sobre isso. Omita se não tiver a certeza.
  • Formatos não suportados são ignorados automaticamente e o resto continua a ser processado — transmita o aviso de omissão.
  • Uma pausa não é uma falha. Uma linha [space-select], [split-confirm], [free-limit], [credit-check] ou [resume-check] significa que a execução parou para lhe perguntar algo — termina com código 0 (por isso nunca parece um erro), mas o trabalho não está concluído. Sempre que uma destas linhas estiver presente, nunca reporte a execução como concluída: transmita-a e aja sobre ela. As linhas são o sinal, não o código de saída.

Configuração (preguiçosa — sem passo prévio)

  1. Chave de API — não é um passo que execute primeiro. O worker autogere-se no momento em que um comando que precise da API Perso é executado: na primeira execução desse tipo, abre uma página do navegador (iniciar sessão, um clique — a chave é armazenada encriptada) ou imprime instruções baseadas em ficheiro se nenhum navegador puder abrir — transmita-as ao utilizador. Numa máquina sem interface gráfica/SSH, o worker ignora totalmente o fluxo do navegador e começa com registo por ficheiro/--import (a página do navegador só pode entregar uma chave à máquina onde é executada) — transmita essas instruções da mesma forma. Nunca acione o registo da chave você mesmo: o worker inicia o connect.mjs/resolve_key.mjs --watch quando necessário, por isso não execute esses comandos, e não execute resolve_key.mjs --check como passo prévio (apenas se o utilizador perguntar explicitamente se uma chave está registada — uma chave em falta não é um erro). Nunca cole a chave no chat. Obtenha uma chave: https://developers.perso.ai/api-keys
  2. ffmpeg/ffprobe — instalado automaticamente apenas quando um vídeo excede o limite do plano e deve ser dividido (aprove se for solicitada permissão). Verificação manual: node scripts/check_deps.mjs.

Executar

Recolha a entrada (caminho local ou URL — volte a perguntar se faltar) e execute em segundo plano — o próprio trabalhador realiza a verificação da chave na primeira necessidade; apenas transmita as suas instruções impressas se o registo for iniciado:

  • Único: node scripts/dubbing.mjs "<ficheiro|URL>" [--source auto] [--target en] [--space "nome do espaço"] [--out resultado.mp4] [--lipsync] [--no-save]
  • Multilíngue / multi-entrada (uma ou mais entradas; URLs e ficheiros podem ser misturados): node scripts/dubbing.mjs "<URL>" "<ficheiro>" --target en,ja — um resultado por entrada × idioma, guardado junto de cada fonte (--out <pasta> recolhe-os).
  • Pasta (lote): node scripts/dubbing.mjs "<pasta>" [--target en,zh] [--recursive] [--out pasta-de-resultados]

Códigos de idioma — --target aceita um código de idioma (en, ja) ou uma etiqueta regional. As variantes regionais existem apenas para Inglês (en = EUA padrão, en-GB = Reino Unido), Português (pt = Brasil padrão, pt-PT = Portugal) e Espanhol (es = México padrão, es-ES = Espanha); en-US, pt-BR e es-MX são grafias aceites desses padrões. Todos os outros idiomas têm uma única variante, e --source precisa apenas do idioma (uma etiqueta regional é tratada como o idioma simples).

  • Região nomeada no pedido → use essa etiqueta exata. Uma região sem variante (ex: inglês australiano) → informe o utilizador de que apenas as opções listadas existem e deixe-o escolher antes de executar.
  • Tokens de duas letras são códigos de idioma, não de países: uk é Ucraniano — inglês britânico é en-GB. A mesma armadilha para ca (Catalão), be (Bielorrusso), eu (Basco). Se a formulação do utilizador puder significar um ou outro, pergunte qual quer dizer antes de executar.
  • Idioma nomeado sem região → a variante padrão. Para esses três idiomas, nomeie o padrão aplicado na nota de entrega (ex: "Espanhol (México) — use es-ES para Espanha").

Localização de gravação — --out aceita uma pasta (um diretório existente ou um caminho que termine em /) que recolhe os resultados no seu interior, ou um caminho de ficheiro para uma única entrada (a extensão real é anexada se o caminho não tiver nenhuma). O padrão é junto de cada ficheiro de origem; não pergunte. No primeiro trabalho da sessão, indique-o na linha de arranque (ex: "Os resultados serão guardados junto dos originais — diga-me agora se preferir uma pasta diferente") e comece imediatamente, sem esperar por resposta. Se o utilizador nomear uma pasta — com este pedido ou a qualquer momento posterior nesta sessão — execute com --out "<pasta>" e continue a usar essa pasta para todos os trabalhos seguintes até que a altere. Se redirecionar após uma execução já iniciada, mova os ficheiros concluídos para lá quando a execução terminar. Exceção: quando todas as entradas são URLs (sem pasta de origem local), pergunte onde guardar antes de começar.

Seleção de espaço — com várias áreas de trabalho, o trabalhador para antes do carregamento, imprime linhas [space-select] (nome | (plano) | créditos restantes) e para. Mostre ao utilizador APENAS essas opções (sem números internos), pergunte qual e execute novamente com --space "<nome do espaço>". Um espaço → sem pergunta; PERSO_SPACE_SEQ fixa-o.

Confirmação de divisão — se a entrada exceder o limite de comprimento ou tamanho e tiver de ser automaticamente dividida e reunida (dublagem, dublagem+lip-sync, ou separação de áudio), o trabalhador para e imprime linhas [split-confirm]. Transmita-as e pergunte ao utilizador: excede o limite de comprimento/tamanho, por isso precisa de divisão automática → processamento → junção, que pode resultar menos polida do que dividir por si próprio — prosseguir automaticamente? Em caso afirmativo, execute novamente o mesmo comando com --allow-split (nada é faturado até este ponto, por isso reexecutar é gratuito). Execuções em lote: --allow-split autoriza todas as divisões na execução.

Não guardar (apenas servidor) — quando o utilizador quiser o vídeo dublado mas não guardado como ficheiro local, adicione --no-save: o trabalhador deixa o resultado na área de trabalho Perso do utilizador e salta a transferência, imprimindo Mantido no servidor, não guardado: … → projeto <seq> (a linha [project-ref] ainda é emitida, para que a dublagem possa ser sincronizada labialmente ou recuperada mais tarde). Apenas vídeos simples/não divididos — o ficheiro reunido de um vídeo dividido precisa de uma transferência local, por isso é guardado normalmente e o trabalhador informa isso. Não pode ser combinado com --lipsync (o vídeo com lip-sync tem de ser transferido).

Plano gratuito (resultados permanecem no Perso) — um espaço gratuito pode dublar, sincronizar lábios e separar normalmente, mas o servidor recusa todas as transferências, por isso o trabalhador nunca guarda um ficheiro lá. Imprime Plano gratuito — <nome>: … pronto no Perso → <url> (transferências precisam de um plano pago) — transmita esse link como o resultado entregue: a execução está concluída, nada falhou e não há nada para retomar. Se o utilizador quiser ficheiros reais, é necessário um plano pago — ofereça o caminho de atualização (veja Atualização de plano e créditos), nunca uma reexecução.

Pausas [free-limit] do plano gratuito — duas delas, ambas antes de qualquer faturação:

  • Pré-visualização de 30 segundos. Uma entrada de dublagem/lip-sync com mais de 30 s para com linhas [free-limit]: no plano gratuito, apenas os primeiros 30 segundos seriam dublados, o resto seria omitido. Transmita a pergunta e, em caso afirmativo, reexecutar o mesmo comando com --allow-preview (o trabalhador corta os primeiros 30 s localmente e submete apenas isso). Um link de plataforma importado pelo Perso não pode ser cortado — aí a resposta é um ficheiro local, um clipe mais curto ou uma atualização.
  • Acima do limite do plano. Média acima do limite de comprimento/tamanho do plano não recebe oferta de divisão no plano gratuito (--allow-split não se aplica): as linhas [free-limit] dizem que um ficheiro mais curto ou uma atualização são a única saída. Transmita-as e pare.

Enquanto corre (para explicar a espera):

  • Divisão: o ficheiro completo é carregado primeiro; apenas uma rejeição por limite do plano instala o ffmpeg e divide sem perdas. URLs externos (YouTube·TikTok·Drive·Vimeo) são tratados no lado do servidor.
  • Fila: todas as entradas × partes × idiomas partilham um único conjunto; uma fila cheia é reavaliada a cada 5 minutos. Um erro de motor numa parte cancela os outros idiomas dessa parte; uma parte silenciosa passa o original; um guarda de inatividade evita que fique pendurado para sempre.
  • Gravação: as partes são reunidas num ficheiro por (entrada × idioma). Uma saída não dividida mantém o nome do ficheiro Perso; uma reunida é <nome-original>.dubbed.<lang>.<ext>; colisões recebem _2,_3….

Lip-sync

O lip-sync (boca sincronizada com o áudio dublado) é executado após a dublagem, no projeto de dublagem concluído. Apenas vídeo — entradas de áudio são rejeitadas. É um trabalho longo: execute em segundo plano e informe o utilizador antecipadamente que demora consideravelmente mais do que a dublagem. Créditos (a faturação do servidor é autoritária): dublagem ≈ segundos ×1 · lip-sync ≈ ×2 · ambos ≈ ×3 — dublagem agora + lip-sync depois custa o mesmo que ambos de uma vez. Fontes 4K+: cada taxa ×3 nos planos pro/empresa/enterprise (ex: um dub+lip-sync de 1 min em 4K ≈ 60×3×3 = 540) — mencione isto quando o vídeo for 4K.

Escolha o fluxo pelo que existe:

  1. Novo vídeo + lip-sync — um comando executa toda a cadeia (dub → lip-sync → guardar); avise que ambas as fases faturam: node scripts/dubbing.mjs "<ficheiro|URL>" --target en --lipsync Se forem impressas linhas [credit-check] e parar, a estimativa excede os créditos restantes: mostre essas linhas (URL de recarga incluído) e reexecute com --force apenas após o utilizador recarregar ou aprovar continuar de qualquer forma.
  2. Dublado anteriormente nesta sessão — cada execução concluída imprime uma linha [project-ref] {...}. Guarde-a; nunca a mostre ao utilizador. Lip-sync sem reedublagem (×2, sem custo de dublagem): node scripts/dubbing.mjs --lipsync-only '<esse JSON do [project-ref]>'
  3. Sem [project-ref] nesta sessão — pergunte se o utilizador sabe o número do projeto a partir do portal Perso (--lipsync-only <número>, ×2). Caso contrário, o vídeo tem de ser dublado novamente (--lipsync, ×3) — confirme antes de reedublar.

Regras:

  • Repetir lip-sync no mesmo projeto fatura novamente (sem desduplicação no servidor). Se esta sessão já fez lip-sync nele, aponte para o ficheiro existente e reexecute apenas com confirmação explícita.
  • Se o lip-sync falhar, o trabalhador guarda o vídeo dublado em vez disso e informa no relatório final — transmita isso claramente; os créditos de dublagem não são desperdiçados.
  • Créditos a esgotar entre a dublagem e o lip-sync: os vídeos dublados são guardados e continuar conclui apenas o lip-sync — transmita o URL de recarga e continue pelo caminho [resume-state] assim que for pago (veja Interrupção e retoma).

Orador (apenas projetos de dublagem)

Para atribuir um novo orador a uma ou mais frases de um projeto já dublado, execute:

node scripts/speaker.mjs "<URL do projeto|projectSeq>" --at "5s,22s,98s" (timecodes/intervalos separados por vírgulas) node scripts/speaker.mjs "<URL do projeto|projectSeq>" --text "primeira linha|segunda linha" (separados por pipe, texto entre aspas) node scripts/speaker.mjs "<URL do projeto|projectSeq>" --sentence 1234,1288 (reexecutar após uma pergunta [sentence-select]) node scripts/speaker.mjs "<URL do projeto|projectSeq>" --list (navegar pelas frases do projeto para encontrar o alvo certo)

Apenas projetos de dublagem — o trabalhador rejeita projetos de legendagem (STT), separação de áudio e lip-sync, e projetos incompletos/falhados. Descobre a área de trabalho sozinho a partir do link do projeto; não precisa de perguntar qual o espaço.

Uma pausa não é uma falha. Uma linha [sentence-select] significa que o trabalhador não conseguiu identificar um único alvo (nada foi dado, nada correspondeu, ou mais de uma frase correspondeu) — termina corretamente para lhe perguntar algo, não porque falhou. A lista numerada abaixo dela (índice, etiqueta de tempo, texto) é segura para transmitir ao utilizador tal como está. Imediatamente após essa lista, uma linha [sentence-ref] imprime um mapa JSON dos mesmos números para os números de frase internos do trabalhador — essa linha é apenas para sua consulta: nunca a mostre nem a leia em voz alta. Assim que o utilizador escolher um número, procure-o nesse mapa e reexecute o mesmo comando com --sentence definido para esse valor. Um bloco [speaker-resolve] ao lado significa que alguns alvos já foram resolvidos mas nada foi ainda escrito — tem a sua própria lista numerada e a sua própria linha [sentence-ref]; a lista --sentence da reexecução deve incluir tanto esses valores já resolvidos como o(s) novo(s) escolhido(s), caso contrário os resolvidos seriam descartados. Quando uma execução imprime mais de um grupo [sentence-select] (vários alvos ambíguos em simultâneo), cada grupo tem a sua própria linha [sentence-ref]. Junte as chaves de todas elas numa única lista --sentence na reexecução.

… [truncado para tradução]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Habilidades Relacionadas