Communitygithub.com

Incrustador de Legendas para Demonstrações de Produtos

Queima legendas estilizadas e posicionadas corretamente em gravações de tela de demonstrações de produtos ou walkthroughs de interface, gerando também o texto das legendas. Ideal para adicionar legendas a vídeos mudos, tornar gravações legíveis para públicos que não falam inglês, ou reposicionar legendas que cobrem a interface.

O que é Incrustador de Legendas para Demonstrações de Produtos?

Esta skill automatiza o processo completo de adicionar legendas a vídeos de demonstração de produtos, resolvendo problemas comuns como texto de interface ilegível, idioma errado e falta de narração. Ela extrai quadros do vídeo para análise visual, identifica a área 'ao vivo' da demonstração, e posiciona as legendas em uma região adjacente que nunca cobre a interface. A skill suporta múltiplos idiomas (incluindo CJK), calcula limites de velocidade de leitura por script, e gera legendas com um estilo visual atraente: texto branco com contorno roxo e um suave halo externo (efeito de duas camadas ASS). A queima das legendas é feita com ffmpeg/libass, incluindo comandos para verificação de pré-requisitos (ffmpeg com libass, fontes CJK) e validação do resultado final. Crucialmente, a skill documenta e evita armadilhas comuns que quebram o workflow silenciosamente, como o uso incorreto do parâmetro `-ss` no ffmpeg que desativa o filtro ASS, coordenadas de preview que não correspondem à resolução original, e legendas que atravessam transições de cena.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add heavenchenggong/demo-video-subtitler

Perguntar na sua IA favorita

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

Documentação

Instrutor de Legendas para Demonstrações de Produtos

Problema

As demonstrações de produtos gravadas em tela falham com seu público por três razões que nada têm a ver com o produto: o texto da interface está no idioma errado, é muito pequeno para ler, e o vídeo geralmente não tem narração alguma (gravações silenciosas). O espectador vê cliques acontecendo, mas não consegue entender o porquê. As legendas resolvem isso — mas apenas se forem estilizadas para serem legíveis sobre uma interface ocupada, colocadas onde não cobrem o que está sendo demonstrado e temporizadas para nunca serem cortadas por uma transição.

Esta skill é o pipeline completo, incluindo os modos de falha não óbvios que custam horas quando descobertos da maneira difícil.

Quando usar

  • "Adicione legendas a este vídeo de demonstração" / "legende esta gravação para a nossa equipe coreana"
  • Uma gravação de tela silenciosa (.mp4, sem fluxo de áudio, ou áudio que é apenas música de fundo) onde a história deve ser contada pelo próprio texto da legenda
  • Uma demonstração de produto apenas em inglês sendo mostrada para um público não falante de inglês
  • Legendas já existem, mas ficam centralizadas na parte inferior e cobrem o painel da demonstração — precisando de posicionamento que siga o foco
  • Gerar um roteiro de leitura para um apresentador que falará sobre o vídeo (veja "Uso complementar")

Não use esta skill para: dublagem com voz sintetizada (isso é um pipeline TTS) ou extração de legendas que já existem em uma plataforma.

Instalação (um comando)

scripts/bootstrap.sh --dry-run          # apenas inspeciona: imprime exatamente o que está faltando
scripts/bootstrap.sh                    # instala o que está faltando (pergunta uma vez)
scripts/bootstrap.sh --yes --lang ja    # automático; também prepara fontes japonesas

bootstrap.sh é idempotente — não faz nada em uma máquina que já está pronta. Ele detecta a plataforma e escolhe o instalador correto (Homebrew / apt / dnf / pacman / winget / scoop), e cai para baixar um ffmpeg estático em ~/.local/bin quando nenhum gerenciador de pacotes está disponível. Execute-o como a primeira ação de qualquer sessão que queimará legendas; skills não têm gancho de instalação, então este script é o instalador.

Pré-requisitos

Execute a verificação integrada primeiro — ela inspeciona a máquina e informa exatamente o que está faltando:

scripts/doctor.sh "Hiragino Sans GB"     # passe a família CJK que você pretende usar

O que é verificado e o comando de instalação quando algo está faltando:

RequisitoPor quêInstalação
ffmpeg compilado com libassqueima as legendas .ass (-vf ass=...)macOS brew install ffmpeg; Windows: build gyan.dev completo; Debian apt install ffmpeg
--enable-fontconfig na compilação do ffmpegresolve fontes pelo nome da família; sem ele você obtém uma face de fallback silenciosaas mesmas compilações acima o incluem
uma família de fontes CJK que o sistema pode resolvero texto da legenda em simacOS: Hiragino Sans GB (pré-instalada) · Windows: Microsoft YaHei (pré-instalada) · Linux: apt install fonts-noto-cjk
python3 (opcional)apenas export_cues.py; biblioteca padrão, nenhum pip installmacOS: xcode-select --install; Linux: apt install python3
bash, zip (opcional)scripts e empacotamento para distribuiçãopré-instalados em todos os lugares

Sem Node, sem ImageMagick, sem pacotes pip, sem chaves de API. Um modelo com capacidade de visão (o próprio agente) lê os quadros — isso não é algo que você instala.

Duas observações de ambiente que pegam:

  • Coloque ffmpeg no PATH, ou exporte sua localização para os scripts: FFMPEG=/caminho/para/ffmpeg scripts/burn.sh ....
  • Windows: libass resolve fontes através de fontconfig/DirectWrite dependendo da compilação. Se as legendas renderizarem na face de tipo errada, instale fontconfig (scoop install fontconfig ou MSYS2) e verifique novamente com fc-match "Microsoft YaHei:bold".

Pipeline

Trabalhe de cima para baixo. Não pule a Fase 2 — toda fase posterior depende do conhecimento da geometria da interface.

Fase 1 — Inventário (2 minutos)

scripts/probe.sh INPUT.mp4

Registre: duração, resolução, fps, bitrate, se existe um fluxo de áudio. Execute a verificação de áudio dentro do script (volume médio + mapa de silêncio).

Decisão a partir da verificação de áudio:

Achado de áudioTipo de legenda
Nenhum fluxo de áudioLegendas de narração — você escreve a história ("o que está acontecendo / por que importa")
Áudio presente, mas sem fala (apenas música)Igual ao anterior. Confirme transcrevendo uma fatia de 10s: uma ferramenta ASR que retorna vazia ou quase vazia em áudio alto significa música, não voz
Fala presenteLegendas de diálogo — transcreva com timestamps primeiro, depois limpe; não invente texto

Fase 2 — Análise visual e geometria (a fase que as pessoas pulam)

Extraia quadros a 2 fps (um clipe de 60s → ~120 quadros; revise cada 4º quadro primeiro para o arco, depois amplie o texto):

scripts/split_frames.sh INPUT.mp4 frames/ 2

Construa três artefatos antes de escrever uma única legenda:

  1. Folha de batida — | tempo | o que mudou na tela | texto na tela (verbatim) |. Uma "batida" é qualquer mudança: uma notificação aparece, um painel desliza, um botão é clicado, uma rolagem acontece, uma troca de página, uma transição. Anote os tipos de transição (flash branco, corte, preto) — as legendas não devem cruzá-los.

  2. Texto da interface, verbatim, lido da resolução original. Quadros de pré-visualização reduzidos borram o texto pequeno da interface e você o transcreverá errado. Corte do arquivo original: ffmpeg -i IN.mp4 -ss 12.5 -frames:v 1 -vf "crop=W:H:X:Y,scale=2*iw:-1" out.jpg (-ss após -i para extração precisa do quadro; veja Armadilhas.)

  3. Mapa de geometria — os limites em pixels do painel "ao vivo" (a coisa sendo demonstrada) em pixels de origem. Meça, não olhe:

    scripts/find_edge.sh INPUT.mp4 30 2880 300     # t=30s, faixa a partir de x=2880, 300px de largura
    

    Então leia a imagem da faixa retornada e anote onde a borda esquerda do painel cai dentro da faixa; adicione esse deslocamento ao x da faixa para obter a borda absoluta. Repita para outras cenas se o layout mudar (por exemplo, um painel de bate-papo abre mais tarde).

Regra que segue do mapa de geometria: a legenda vive na região livre adjacente ao painel de demonstração, nunca em cima dele. Veja a Fase 5.

Fase 3 — Escreva o texto da legenda

Duas regras governam tudo:

  • Uma ideia por legenda. Máximo de 2 a 3 linhas curtas. Uma legenda é uma sentença, não um parágrafo.
  • Orçamento de velocidade de leitura. CJK: 3,5–5,5 caracteres por segundo é confortável; acima de 6 é uma correria; abaixo de 3 parece morto. Latim: 12–18 caracteres por segundo. Calcule, não adivinhe. scripts/export_cues.py imprime a densidade por legenda depois que você tem um arquivo .ass — itere contra esse número.

Regras de temporização da legenda:

  • Inicie a legenda quando a batida visual ocorrer, não antes. Se uma notificação deslizar em 1,0s, a legenda começa em 1,0s.
  • Termine as legendas antes de uma transição (flash branco/corte), deixando pelo menos 0,8s de silêncio através dela. Uma legenda que atravessa uma transição parece um problema técnico.
  • Deixe lacunas reais. Três a cinco segundos em branco por minuto mantém o vídeo respirando; legendas de ponta a ponta cansam o espectador.
  • Para legendas de narração, coloque o motivo na legenda, não a mecânica: "o agente agiu por conta própria" é melhor que "uma notificação apareceu no canto superior direito".

Pare aqui e obtenha a aprovação do texto. Texto aprovado → estilização. Texto rejeitado após a estilização custa uma segunda renderização por nada.

Fase 3b — Escolha o idioma da legenda

O pipeline é independente de idioma, mas três coisas devem ser decididas por idioma antes da estilização.

1. Família de fontes — escolha uma que a plataforma possa resolver (verifique com scripts/doctor.sh <idioma>):

Idioma da legendamacOSWindowsLinux
Chinês (zh)Hiragino Sans GB / PingFang SCMicrosoft YaHeiNoto Sans CJK SC
Japonês (ja)Hiragino SansYu Gothic / MeiryoNoto Sans CJK JP
Coreano (ko)Apple SD Gothic NeoMalgun GothicNoto Sans CJK KR
Latim (en/fr/de/es…)Helvetica NeueSegoe UIInter / DejaVu Sans

2. Velocidade de leitura — o orçamento depende do script; scripts/export_cues.py seleciona o correto automaticamente (--lang substitui) e sinaliza legendas que o excedem:

ScriptConfortávelSinalizar como muito rápido
Han / Kana (zh, ja)3,5–5,5 chars/s> 6,0
Hangul (ko)4,0–6,0 chars/s> 6,5
Latim12–18 chars/s> 19

3. Quebra de linha — Chinês e japonês não têm espaços entre palavras: quebre na pontuação (U+FF0C, U+3001, U+3002, U+FF1A) e nunca divida um nome de produto. Coreano e latim quebram nos espaços; mantenha uma partícula coreana anexada ao seu substantivo. Se uma linha não couber, re-embrulhe antes de encolher a fonte — uma face de tipo menor perde mais legibilidade do que uma linha extra.

4. Largura da linha por script — a largura do glifo não é a mesma entre scripts, então o mesmo Fontsize dá comprimentos de linha diferentes. Orçamente as linhas como floor(disponivel_px / (fontsize * k)), onde k é aproximadamente 1,0 para Han e 1,05–1,1 para Hangul e Kana (eles definem mais largos), e 0,5 para Latim em média (varia com a palavra).

Medido em 4K com Fontsize 165: 13 caracteres Hangul ≈ 2.150 px (seguro em um slot de 2.450 px), enquanto 18 caracteres ≈ 2.970 px — isso transborda e empurra a linha para fora da borda esquerda do quadro. Quando uma linha não couber, re-embrulhe-a; não encolha a fonte para fazê-la caber.

Legendas bilíngues (original + tradução): apenas quando ambas as linhas são curtas. Duas linhas de idioma dobram a carga de leitura e, em uma demonstração, competem com a interface. Prefira um idioma por versão do arquivo, a menos que o cliente peça o contrário; quando for necessário, empilhe o original em cima e a tradução abaixo, e orçamente todo o bloco contra a velocidade de leitura da tradução.

Scripts da direita para a esquerda (árabe, hebraico): libass suporta RTL, mas a qualidade da modelagem depende do harfbuzz da compilação. Renderize um quadro de pré-visualização antes de confirmar — verifique se as letras se juntam corretamente e se a âncora de alinhamento ainda faz sentido.

O peso da fonte difere por script. Famílias japonesas e coreanas geralmente renderizam visualmente maiores do que uma família chinesa no mesmo Fontsize; verifique com um quadro de pré-visualização e ajuste a olho, não por regra.

Fase 4 — Estilo (o brilho de duas camadas)

Um único estilo ASS não pode produzir "texto branco com um contorno colorido grosso e um halo colorido suave" — Outline desenha apenas um anel. Use dois eventos por legenda em duas camadas:

CamadaPreenchimentoContornoDesfoquePropósito
0transparente (&HFF000000)largo, roxo semitransparente\blur 20–30o halo
1brancomais estreito, roxo sólidonenhum / \blur1o texto legível

Ponto de partida (veja assets/caption-template.ass). As cores são &HAABBGGRR — alfa 00 é opaco, FF é totalmente transparente e a ordem dos bytes é BGR:

roxo RGB(124,46,240)  →  &H00F02E7C
halo, 35% opaco        →  &H55F02E7C

Escala por PlayRes, não por gosto: uma renderização 4K usou fontsize 180 / outline 16 / halo 28 / blur 24; a mesma aparência em 1080p é 80 / 7 / 12 / 12. Defina PlayResX/Y para a resolução de saída e mantenha ScaledBorderAndShadow: yes.

Fase 5 — Posicionamento que segue o foco

Centralizado na parte inferior é errado para demonstrações: a parte inferior geralmente é a interface, e o painel de demonstração é a única coisa que deve permanecer visível. Ancore cada legenda na região livre adjacente a o que está sendo mostrado:

Foco desta legendaÂncoraPor quê
Um painel lateral / painel de bate-papo está aberto\an6\pos(<painel_esquerda - 40>, <painel_meio_vertical>)borda direita abraça o painel, o bloco cresce para a esquerda, mudanças de largura não precisam de recálculo
Um toast/notificação no canto superior direito\an3\pos(<toast_direita>, <toast_fundo + 80>)âncora no canto inferior direito coloca o bloco logo abaixo do toast
Página de largura total, sem painel\an5\pos(<centro_visual_x>, <y entre dois blocos de conteúdo>)centralizado, mas colocado em uma lacuna medida — não no centro geométrico
Cartão de título com tipo grande embutido\an5\pos(centro_x, ABAIXO do título)o centro geométrico colide com o próprio título do vídeo

Calcule a largura máxima da linha antes de escrever: max_line_px ≈ fontsize × caracteres. Se uma linha exceder a região livre, re-embrulhe-a (nunca encolha a fonte apenas para uma legenda) — divida na pontuação e mantenha os nomes dos produtos intactos.

Para blocos ancorados à direita, o derramamento de algumas dezenas de pixels sobre um fundo plano é aceitável e parece intencional; derramamento sobre o painel de demonstração não é.

Mantenha a âncora longe da borda do quadro. O contorno e o halo estendem-se além da caixa do glifo em aproximadamente outline + blur pixels (em 4K com outline 15 / blur 22, isso é ~40 px, mais anti-aliasing). Uma âncora \an3 estacionada a 50 px da borda direita, portanto, tem seu halo cortado e parece uma palavra quebrada. Estacione âncoras pelo menos 150 px dentro do quadro e verifique o resultado em um quadro de pré-visualização — o corte é invisível no arquivo .ass e óbvio na tela.

Fase 6 — Queima

scripts/burn.sh INPUT.mp4 subs.ass OUT.mp4 [crf]

Isso é -i IN -vf "ass=subs.ass" -c:v libx264 -crf 17~18 -pix_fmt yuv420p -movflags +faststart, mantendo a trilha de áudio original. Legendas fixas são o padrão correto para demonstrações — elas sobrevivem a qualquer player, upload e compartilhamento de tela; envie um .ass/.srt junto apenas se solicitado.

Fase 7 — Verificação

Renderize imagens baratas primeiro e, em seguida, verifique o arquivo codificado:

scripts/preview_frame.sh INPUT.mp4 subs.ass 16.0 /tmp/check1.jpg

Verifique cada quadro para: texto sobre o painel de demonstração, texto fora do quadro, quebra de linha inesperada, uma legenda que deveria ter terminado, halo que se transformou em mingau sobre um fundo brilhante. Em seguida, re-extraia 3 quadros do arquivo finalizado (as legendas estão gravadas, a qualidade é final) e confirme novamente.

Armadilhas (cada uma custou tempo real para encontrar)

  1. -ss antes de -i silencia o filtro ass. A busca de entrada redefine os timestamps para zero, então o filtro renderiza o estado da legenda em t≈0 para cada quadro. Resultado: o vídeo queima sem legendas, e ffmpeg não imprime nenhum erro. Sempre coloque -ss após -i (busca de saída), ou adicione -copyts. Os scripts incluídos já fazem isso.
  2. As coordenadas do quadro de pré-visualização mentem. Um quadro dimensionado para 1280×720, mas exibido para você em...

...

[truncado para tradução]

Habilidades Relacionadas