O que demo-reel faz?
Tu produzes o vídeo completo sozinho: a pessoa fornece o produto e o que mostrar, e recebe de volta um MP4 que pode publicar. Tudo no ecrã é o produto real, gravado ao vivo; o polimento (moldura da janela, movimentos de câmara, legendas, cartões de título e fim) é adicionado depois a partir da gravação.
O pipeline e o ficheiro que cada passo produz:
| Passo | Comando | Produz |
|---|---|---|
| 1. Storyboard | tu, com a pessoa | 3–5 funcionalidades, uma legenda cada |
| 2. Cenário | escrever scenario.mjs | os passos que um utilizador daria |
| 3. Gravação | bin/reel take scenario.mjs takes/take1 | take1.mov (imagem + som da app), take1.json (eventos, posições dos elementos) |
| 4. Edição | escrever edit.json | cenas, planos, legendas, marca |
| 5. Stills | bin/reel check edit.json, bin/reel layers edit.json e bin/reel stills edit.json 1,4,9 | problemas detetados cedo; frames de pré-visualização |
| 6. Legendas | bin/reel subtitles edit.json e depois ler e corrigir build/subtitles.srt | o que é dito, como legendas |
| 7. Renderizar | bin/reel render edit.json renders/x.mp4 --format all | o vídeo em cada formato, com o seu .srt |
| 8. Verificar | bin/reel sheet renders/x.mp4 1,4,9,… | folha de contactos, duração, volume |
examples/sawt/ é um exemplo completo (uma extensão Chrome que lê artigos em voz alta). Abre o seu
scenario.mjs e edit.json antes de escreveres os teus. docs/edit-format.md é a referência do ficheiro de edição;
docs/lessons.md lista o que correu mal da primeira vez, por isso lê-o antes de gravar.
0. Configuração (uma vez)
Executa bin/reel doctor primeiro: verifica todas as ferramentas e permissões e diz o que corrigir.
bin/reel setup constrói o gravador (Swift, ScreenCaptureKit), instala playwright-core e Chrome
for Testing. Também necessário: ffmpeg, uv, Google Chrome (para renderizar as camadas de sobreposição). O terminal
onde estás a executar precisa de permissão de Gravação de Ecrã e Áudio do Sistema (System Settings → Privacy &
Security); se o gravador reportar que não está permitido, pede à pessoa que o conceda e reinicie o
terminal.
1. Storyboard
Acordem, em poucas linhas, antes de gravar qualquer coisa:
- as funcionalidades, por ordem, cada uma como uma legenda: um título curto ("Zoom na palavra") e um cabeçalho de no máximo duas linhas curtas, com o benefício em
<b>("Acompanhe. Cada palavracresce enquanto é falada."); - que conteúdo real usar para demonstração: uma página pública, uma conta de exemplo, dados de seed. Escolhe conteúdo que faça a funcionalidade parecer o melhor possível e verifica se funciona (para Sawt: um artigo cujas palavras difíceis têm cartões, num site onde os cartões tenham espaço ao lado da coluna);
- a marca: cor de destaque, uma variante clara, tons de fundo, logótipo; texto do cartão de título e fim.
Formato predefinido: 1080×1350 (4:5), 25–35 s — preenche a maior parte do feed do telemóvel, e a maioria das pessoas vê sem som, por isso as legendas devem contar a história sozinhas. Pergunta onde será publicado: 1:1, 9:16 e 16:9 vêm da mesma edição (--format), por isso oferece-os. Verifica os stills de cada formato que renderizares: um plano que enquadra bem em 4:5 pode cortar um cabeçalho em 1:1; ajusta por formato ("1:1": {"dy": 20}).
Quando o produto fala (ou a gravação tem narração), cria legendas: reel subtitles, depois lê
o .srt e corrige nomes e jargão antes de renderizar — a transcrição é boa, não perfeita.
Coloca palavras difíceis em subtitles.words para a orientar.
2. Cenário
Um cenário é um módulo ES (vê drive/take.mjs para a API completa):
export const config = { url: "https://…", width: 1700, height: 1090, extension: "./ext" };
export async function setup(api) { /* definições, login; api.rect("title", "h1") para alvos de câmara */ }
export async function run(api) { /* a demonstração; api.mark("step") em cada momento onde vais cortar */ }
export async function after(api) { /* stills para mostrar como cenas de imagem, p. ex. um popup a 3x */ }
- Marca cada momento onde vais cortar ou mover a câmara (
api.mark("sentence", {n})). A edição ancora-se a estas marcas, por isso uma gravação que corre mais rápido ou mais lento ainda corta no sítio certo. - Grava alvos de câmara com
api.rect(name, selector | fn, arg)em píxeis da viewport. Elementos numa shadow root fechada não podem ser medidos: calcula onde vão estar (vê os cartões Sawt). - Produtos orientados a cliques precisam de um ponteiro visível. A automação não move nenhum cursor real, por isso formas aparecem e botões pressionam-se sozinhos. Chama
api.pointer.show()emsetup, depois controla comapi.pointer.click(selector | [x, y]),.drag(from, to),.move(x, y),.type(text)e.key(k): uma seta na página segue, os cliques ondulam, os movimentos são suaves e a digitação tem ritmo humano. Clica em controlos por seletor (umtitleouaria-labelé geralmente estável) para que as suas posições venham da página. - Conteúdo de canvas (desenhos, gráficos, mapas) não tem elemento para medir: grava a caixa onde desenhaste com
api.rect(name, {x, y, width, height})em px CSS. - Extensões Chrome: executa ações através do código da própria extensão com
api.inWorker(fn). Uma extensão que depende deactiveTabprecisa de uma cópia de gravação com acesso ao host, porque a automação não consegue pressionar os atalhos do navegador (vêexamples/sawt/prepare.sh). Não mudes nada que um espectador veja. - Popups e outra UI pequena: captura-os em
after()com deviceScaleFactor 3 usando CDP (vê o exemplo) e mostra-os como uma cena de imagem. Captura ambos os estados de um toggle no mesmo momento clicando no controlo real, não recarregando.
Executa-o, depois olha para a gravação antes de editar: ffmpeg -ss 6 -i takes/take1.mov -frames:v 1 x.png
e lê o PNG. Verifica se a página está estilizada, se a funcionalidade disparou, se nada a cobre. Refaz a gravação à vontade — uma gravação custa um minuto.
3. Edição
Escreve edit.json (referência: docs/edit-format.md). Regras que o fazem parecer produzido, não gravado:
- Corta nas pausas.
bin/reel speech take1.movlista onde há som; os segmentos começam pouco antes de um passo e terminam antes do próximo começar. Ancora-os a marcas:"sentence#5-0.15". - Conteúdo lado a lado não cabe em janelas altas. Uma barra de ferramentas à esquerda e um diagrama à direita podem precisar de mais largura do que uma janela 4:5 mostra;
reel checkavisa, por formato, quanto um plano ajustado perderá. Encaixa menos coisas, ou ajusta o plano para esse formato. - Planos a partir de rects.
{"fit": ["title", {"rect": "card1", "dh": 330}], "pad": 60}. Um plano geral largo, depois aproxima-te do que a legenda fala. Mantém o texto com pelo menos ~20 px de altura no output; um plano largo pode ficar mais pequeno por um momento, nunca por muito tempo. - Uma legenda por cena, visível durante toda a cena; muda de legenda apenas num movimento de câmara.
- Deixa os movimentos respirar: 1,0–1,5 s por movimento de câmara, mantém pelo menos 1,5 s depois de aterrar.
- Cartão de título 2–2,5 s, cartão final 3–3,5 s. Cenas de imagem (um popup, um painel de definições) 3–4 s.
Velocidade
Uma renderização 4:5 de 30 segundos demora cerca de 3 minutos num portátil de 6 núcleos: os frames renderizam-se em blocos paralelos (4 por defeito; --jobs N), unidos sem reencodificação, e as camadas inalteradas são reutilizadas. Enquanto a edição ainda está em movimento, usa reel render … --draft (15 fps, codificador rápido, cerca de metade do tempo) e reel stills; renderiza a versão final quando os stills estiverem corretos.
4. Verificar, sempre
bin/reel layersebin/reel stillsno início, meio e fim de cada cena e em cada movimento de câmara. Lê cada PNG. Procura: texto ou UI cortados nos bordos do frame, um cabeçalho meio visível no topo, uma legenda sobre algo importante, um frame que é só página vazia.- Renderiza, depois
bin/reel sheetem todo o vídeo e lê. - A duração deve ser a que planeaste; o volume cerca de −16 LUFS quando o produto faz som.
- Sincronia: o momento em que um passo aparece no ecrã e o seu som começa devem coincidir com a gravação.
Depois coloca o MP4 à frente da pessoa, com a miniatura (build/layers/title.png), e dize claramente o que é real e o que foi alterado para a gravação.
Música
Por defeito, o sistema escolhe uma base que se adequa ao vídeo (docs/music.md): analisa o perfil do vídeo (duração, fala, ritmo, palavras das legendas), classifica candidatos instrumentais licenciados — a pasta music/ da pessoa, depois a biblioteca CC0 incluída (library/), e online apenas se nada local servir — por tempo, energia e estabilidade medidos, e mantém o melhor. Executa reel music auto edit.json --audition renders/x.mp4 para ver a classificação e obter uma pré-visualização das melhores faixas. Tu não consegues ouvir, por isso entrega as pré-visualizações à pessoa antes de considerar o vídeo concluído. Quando as melhores faixas são apenas links (o site bloqueia downloads com script), dá os links à pessoa; ela descarrega uma e executa reel music add <file> --candidate N. Se ela trouxer a sua própria faixa, regista a licença com reel music add e coloca-a na edição. Dá-lhes sempre o .credits.txt junto com a renderização e diz quando a sua licença precisa de um crédito publicado.
Limitações
- A gravação é apenas macOS (ScreenCaptureKit). A composição e as camadas funcionam em qualquer sistema.
- Apenas produtos de navegador até agora; uma aplicação de desktop precisa do seu próprio driver (scripting de acessibilidade), mas o gravador (
--app <bundle id>) e tudo o que vem depois já funciona para qualquer app. - Gerar música (
reel music generate) precisa de um modelo local ligado; ACE-Step é sugerido mas ainda não testado com demo-reel.