primocode 10.16.0 → 10.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/edit-ia-pro.txt +32 -0
- package/LICENSES/fontes-OFL.txt +476 -0
- package/LICENSES/hyperframes-Apache-2.0.txt +205 -0
- package/LICENSES/permanent-marker-Apache-2.0.txt +204 -0
- package/LICENSES/selfie-multiclass-Apache-2.0.txt +227 -0
- package/LICENSES/three-MIT.txt +23 -0
- package/LICENSES/video-use-MIT.txt +24 -0
- package/LICENSES/woven-sfx-CC0.txt +16 -0
- package/LICENSES/yunet-MIT.txt +21 -0
- package/README.md +2 -2
- package/bin/primocode.js +28 -8
- package/editor/LICENSE.md +11 -0
- package/editor/README.md +321 -0
- package/editor/SKILL.md +307 -0
- package/editor/THIRD_PARTY_NOTICES.md +228 -0
- package/editor/assets/baixar.json +591 -0
- package/editor/assets/fonts/anton/OFL.txt +93 -0
- package/editor/assets/fonts/caveat/OFL.txt +93 -0
- package/editor/assets/fonts/figtree/OFL.txt +93 -0
- package/editor/assets/fonts/fonts.json +10 -0
- package/editor/assets/fonts/montserrat/OFL.txt +93 -0
- package/editor/assets/fonts/permanentmarker/LICENSE.txt +202 -0
- package/editor/assets/models/SELFIE_MULTICLASS_LICENSE.txt +227 -0
- package/editor/assets/models/YUNET_LICENSE.txt +21 -0
- package/editor/assets/sfx/licencas/bass_drop.txt +32 -0
- package/editor/assets/sfx/licencas/cash.txt +76 -0
- package/editor/assets/sfx/licencas/charge.txt +31 -0
- package/editor/assets/sfx/licencas/click.txt +46 -0
- package/editor/assets/sfx/licencas/coin.txt +50 -0
- package/editor/assets/sfx/licencas/count.txt +47 -0
- package/editor/assets/sfx/licencas/data.txt +31 -0
- package/editor/assets/sfx/licencas/error.txt +32 -0
- package/editor/assets/sfx/licencas/flash.txt +31 -0
- package/editor/assets/sfx/licencas/gears.txt +82 -0
- package/editor/assets/sfx/licencas/keyboard.txt +48 -0
- package/editor/assets/sfx/licencas/metal_hit.txt +62 -0
- package/editor/assets/sfx/licencas/metal_riser.txt +61 -0
- package/editor/assets/sfx/licencas/mouse_click.txt +50 -0
- package/editor/assets/sfx/licencas/notification.txt +54 -0
- package/editor/assets/sfx/licencas/pop.txt +38 -0
- package/editor/assets/sfx/licencas/rewind.txt +32 -0
- package/editor/assets/sfx/licencas/rise.txt +46 -0
- package/editor/assets/sfx/licencas/sinteticos.txt +21 -0
- package/editor/assets/sfx/licencas/snap.txt +50 -0
- package/editor/assets/sfx/licencas/success.txt +40 -0
- package/editor/assets/sfx/licencas/synth_hit.txt +32 -0
- package/editor/assets/sfx/licencas/tick.txt +14 -0
- package/editor/assets/sfx/licencas/whoosh.txt +47 -0
- package/editor/assets/sfx/licencas/wind.txt +31 -0
- package/editor/assets/sfx/sfx.json +832 -0
- package/editor/assets/sfx/sfx_sinteticos.json +317 -0
- package/editor/assets/sfx/sfx_woven.json +387 -0
- package/editor/assets/sfx/woven/LICENCA.md +16 -0
- package/editor/fichas/briefing-do-video.md +45 -0
- package/editor/fichas/conferencia-da-amostra.md +56 -0
- package/editor/fichas/matriz-de-ganchos.csv +3 -0
- package/editor/fichas/padrao.json +16 -0
- package/editor/fichas/planilha-de-cenas.csv +4 -0
- package/editor/fichas/planilha-de-versoes.csv +4 -0
- package/editor/fichas/plano-em-blocos.md +32 -0
- package/editor/fichas/registro-de-materiais.json +27 -0
- package/editor/helpers/assets_ocr/ocr_vision.swift +41 -0
- package/editor/helpers/bordas_precisas.py +272 -0
- package/editor/helpers/camera_viva.py +426 -0
- package/editor/helpers/captions.py +601 -0
- package/editor/helpers/common.py +308 -0
- package/editor/helpers/compose_final.py +3555 -0
- package/editor/helpers/conferir_corte.py +234 -0
- package/editor/helpers/conferir_dados.py +405 -0
- package/editor/helpers/contact_sheet.py +282 -0
- package/editor/helpers/corte_por_onda.py +433 -0
- package/editor/helpers/corte_seco.py +595 -0
- package/editor/helpers/denoise.py +971 -0
- package/editor/helpers/efeitos.py +408 -0
- package/editor/helpers/efeitos_gerar.py +159 -0
- package/editor/helpers/elevenlabs_api.py +442 -0
- package/editor/helpers/face_layout.py +570 -0
- package/editor/helpers/fetch_images.py +423 -0
- package/editor/helpers/ganho_por_trecho.py +214 -0
- package/editor/helpers/gen_image.py +312 -0
- package/editor/helpers/gen_music.py +316 -0
- package/editor/helpers/gen_sfx.py +148 -0
- package/editor/helpers/grade.py +307 -0
- package/editor/helpers/icloud.py +119 -0
- package/editor/helpers/make_sfx.py +940 -0
- package/editor/helpers/matte.py +1342 -0
- package/editor/helpers/medir_referencia.py +2232 -0
- package/editor/helpers/mixar_trilha.py +354 -0
- package/editor/helpers/montar_corte.py +295 -0
- package/editor/helpers/motion/__init__.py +13 -0
- package/editor/helpers/motion/engine.py +1915 -0
- package/editor/helpers/motion/registry.py +510 -0
- package/editor/helpers/motion/render.py +665 -0
- package/editor/helpers/motion/templates/barra_progresso.py +370 -0
- package/editor/helpers/motion/templates/carimbo.py +132 -0
- package/editor/helpers/motion/templates/checklist.py +271 -0
- package/editor/helpers/motion/templates/comentario_cta.py +380 -0
- package/editor/helpers/motion/templates/contador.py +222 -0
- package/editor/helpers/motion/templates/destaque.py +263 -0
- package/editor/helpers/motion/templates/etiqueta_preco.py +461 -0
- package/editor/helpers/motion/templates/grafico_barras.py +510 -0
- package/editor/helpers/motion/templates/grafico_linha.py +462 -0
- package/editor/helpers/motion/templates/notificacao.py +266 -0
- package/editor/helpers/motion/templates/palavra_impacto.py +410 -0
- package/editor/helpers/motion/templates/passos.py +321 -0
- package/editor/helpers/motion/templates/riscado.py +298 -0
- package/editor/helpers/motion/templates/selo_garantia.py +150 -0
- package/editor/helpers/motion_render.py +241 -0
- package/editor/helpers/motion_sugerir.py +961 -0
- package/editor/helpers/noise_check.py +134 -0
- package/editor/helpers/pack_transcripts.py +223 -0
- package/editor/helpers/palavras_na_onda.py +176 -0
- package/editor/helpers/plano_sfx.py +839 -0
- package/editor/helpers/portao.py +427 -0
- package/editor/helpers/preview_server.py +1177 -0
- package/editor/helpers/rastrear_rosto.py +298 -0
- package/editor/helpers/render_cut.py +1256 -0
- package/editor/helpers/respiros.py +89 -0
- package/editor/helpers/sincronizar_cameras.py +571 -0
- package/editor/helpers/speech_regions.py +423 -0
- package/editor/helpers/style_catalog.json +231 -0
- package/editor/helpers/style_samples.py +246 -0
- package/editor/helpers/tela_verde.py +2113 -0
- package/editor/helpers/text_render.py +2059 -0
- package/editor/helpers/texto_na_tela.py +366 -0
- package/editor/helpers/timeline_view.py +292 -0
- package/editor/helpers/tira_de_quadros.py +113 -0
- package/editor/helpers/transcribe.py +734 -0
- package/editor/helpers/transcribe_batch.py +129 -0
- package/editor/helpers/trilhas.py +1146 -0
- package/editor/helpers/trilhas_humores.json +66 -0
- package/editor/helpers/valores.py +187 -0
- package/editor/helpers/verify_cut.py +820 -0
- package/editor/helpers/voice_levels.py +233 -0
- package/editor/helpers/voz_check.py +386 -0
- package/editor/helpers/voz_limpa.py +81 -0
- package/editor/helpers/watch_preview.py +372 -0
- package/editor/modelo-projeto/LEIA.md +402 -0
- package/editor/modelo-projeto/assets/fontes/OFL-Caveat.txt +93 -0
- package/editor/modelo-projeto/assets/fontes/OFL-JetBrainsMono.txt +93 -0
- package/editor/modelo-projeto/assets/fontes/OFL-Montserrat.txt +93 -0
- package/editor/modelo-projeto/assets/fontes/larguras.json +1 -0
- package/editor/modelo-projeto/assets/three/BufferGeometryUtils.js +1438 -0
- package/editor/modelo-projeto/assets/three/GLTFLoader.js +4895 -0
- package/editor/modelo-projeto/assets/three/LICENSE +21 -0
- package/editor/modelo-projeto/assets/three/ORIGEM.txt +17 -0
- package/editor/modelo-projeto/assets/three/RoomEnvironment.js +185 -0
- package/editor/modelo-projeto/assets/three/three.core.min.js +6 -0
- package/editor/modelo-projeto/assets/three/three.module.min.js +6 -0
- package/editor/modelo-projeto/build.py +4828 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_antes_depois.html +199 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_arquivo.html +232 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_busca.html +315 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_comando.html +304 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_conversa.html +217 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_esquema.html +289 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_medidor.html +249 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_notas.html +233 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_caminho.html +197 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_explodida.html +152 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_tela.html +167 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_volume.html +124 -0
- package/editor/modelo-projeto/compositions/cenas/3d/motor-three.js +728 -0
- package/editor/modelo-projeto/compositions/cenas/LEIA.md +177 -0
- package/editor/modelo-projeto/ferramentas/medir_fontes.py +65 -0
- package/editor/modelo-projeto/ferramentas/pessoa_recortada.py +176 -0
- package/editor/modelo-projeto/ferramentas/rastrear_maos.py +189 -0
- package/editor/modelo-projeto/hyperframes.json +12 -0
- package/editor/modelo-projeto/package.json +11 -0
- package/editor/modelo-projeto/projeto.json +16 -0
- package/editor/preview/app.css +1009 -0
- package/editor/preview/app.js +2122 -0
- package/editor/preview/index.html +307 -0
- package/editor/pyproject.toml +23 -0
- package/editor/references/3d.md +236 -0
- package/editor/references/animacao-catalogo.md +672 -0
- package/editor/references/animacao.md +498 -0
- package/editor/references/comandos.md +92 -0
- package/editor/references/corte-seco-como-funciona.md +50 -0
- package/editor/references/corte-seco.md +88 -0
- package/editor/references/corte.md +290 -0
- package/editor/references/direcao-por-blocos.md +218 -0
- package/editor/references/enquadramento.md +654 -0
- package/editor/references/estilos-prontos.md +355 -0
- package/editor/references/estudio.md +100 -0
- package/editor/references/exemplo-eventos.json +67 -0
- package/editor/references/lettering.md +252 -0
- package/editor/references/modelos.md +494 -0
- package/editor/references/phase2.md +1007 -0
- package/editor/references/referencia-aplicar.md +203 -0
- package/editor/references/referencia-medir.md +375 -0
- package/editor/references/revisao.md +335 -0
- package/editor/references/som-e-trilha.md +146 -0
- package/editor/references/tabela-de-sons.md +130 -0
- package/editor/references/variacoes.md +234 -0
- package/editor/uv.lock +1141 -0
- package/lib/act.js +36 -8
- package/lib/catalogo.js +4 -0
- package/lib/chamada-torta.js +81 -0
- package/lib/editor-pro.js +786 -0
- package/lib/entrega.js +58 -0
- package/lib/estudio/conferencia-visual.js +76 -0
- package/lib/estudio/diretor.js +6 -1
- package/lib/estudio/exportar.js +3 -1
- package/lib/estudio/gosto.js +45 -4
- package/lib/estudio/index.js +8 -5
- package/lib/estudio/kit-ae/base.jsx +119 -13
- package/lib/estudio/kit-ae/cenas.jsx +47 -15
- package/lib/estudio/kit-ae/guarda.jsx +274 -0
- package/lib/estudio/kit-ae/primitivas.jsx +180 -24
- package/lib/estudio/maquina-diretor.js +61 -7
- package/lib/estudio/maquina-foto.js +177 -0
- package/lib/estudio/maquina-guarda.js +207 -0
- package/lib/estudio/maquina-layout.js +22 -1
- package/lib/estudio/maquina.js +60 -11
- package/lib/estudio/referencias.js +1 -1
- package/lib/estudio/visao/visao.swift +97 -0
- package/lib/estudio/visao.js +60 -0
- package/lib/local/cerebro.json +192 -6
- package/lib/local/motor.js +5 -2
- package/lib/mcp.js +105 -7
- package/lib/nuvem.js +11 -1
- package/lib/outra-pasta.js +1 -1
- package/lib/passagem.js +50 -0
- package/lib/perigo.js +29 -12
- package/lib/protecao.js +134 -0
- package/lib/sandbox.js +11 -4
- package/lib/titulo-conversa.js +46 -0
- package/lib/tools.js +3 -0
- package/lib/ui.js +1 -1
- package/package.json +3 -2
- package/skills/editar-meu-video/SKILL.md +6 -2
- package/skills/editar-video/SKILL.md +113 -0
- package/studio/pessoa.py +52 -0
- package/voz/primo_voz/app.py +43 -4
- package/voz/primo_voz/chat.html +17 -6
- package/voz/primo_voz/painel_dados.py +134 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
# Enquadramento: pessoa, moldura, tela verde e planos
|
|
2
|
+
|
|
3
|
+
Você decide, trecho por trecho, como a pessoa aparece e quanto espaço ela divide com o que está sendo
|
|
4
|
+
explicado. O `build.py` do projeto-modelo faz a conta do enquadramento pelo rosto medido, anima a troca e põe a
|
|
5
|
+
legenda e as peças fora do rosto. O vídeo continua sendo o `cut.mp4` do corte; a voz nunca para.
|
|
6
|
+
|
|
7
|
+
## Como falar com a pessoa
|
|
8
|
+
|
|
9
|
+
- Português simples, frases curtas. Nada de código, JSON ou caminho comprido na conversa.
|
|
10
|
+
- Conte o plano em palavras do dia a dia, com o tempo em 00:12: "De 00:00 a 00:21 você em tela cheia. Em
|
|
11
|
+
00:22 você vai para um quadrinho embaixo e a lista aparece em cima. Em 00:28 volta pra tela cheia."
|
|
12
|
+
- Autorização em camadas: se a pessoa já autorizou fazer tudo, conte e siga; se pediu para aprovar antes,
|
|
13
|
+
espere. O teste de recorte é a exceção (seção "Portão do recorte").
|
|
14
|
+
- Uma decisão por vez. Se ela disser "decide você", decida e conte em uma linha.
|
|
15
|
+
|
|
16
|
+
## Antes de começar
|
|
17
|
+
|
|
18
|
+
Precisa existir, na pasta `edit` do corte (`<EDIT>`): `cut.mp4` aprovado, `cut_timeline.json`,
|
|
19
|
+
`transcripts/cut.json` (a transcrição do corte) e `face_layout.json`. Se faltar o `face_layout.json`:
|
|
20
|
+
|
|
21
|
+
`uv run --directory "<SKILL>" python helpers/face_layout.py --edit-dir '<EDIT>'`
|
|
22
|
+
|
|
23
|
+
(`<SKILL>` é a pasta desta skill.)
|
|
24
|
+
|
|
25
|
+
O projeto HyperFrames é uma cópia da pasta `modelo-projeto` desta skill (`<SKILL>/modelo-projeto`), feita
|
|
26
|
+
pelo próprio modelo, perto dos vídeos:
|
|
27
|
+
|
|
28
|
+
`python3 '<SKILL>/modelo-projeto/build.py' novo '<VIDEOS>/sala' --edit '<EDIT>'`
|
|
29
|
+
|
|
30
|
+
Ele anota no `projeto.json` a skill de onde o projeto veio (`"skill"`) e a pasta `edit`; as ferramentas do
|
|
31
|
+
projeto (recorte da pessoa, mãos) usam essa skill, e não outra instalada no computador. Nunca edite o modelo
|
|
32
|
+
original. O `LEIA.md` do modelo tem os campos.
|
|
33
|
+
|
|
34
|
+
## Primeiro, assista o trecho tocando
|
|
35
|
+
|
|
36
|
+
Um quadro solto não diz se o enquadramento aguenta a fala inteira. Antes de decidir, toque o trecho e procure:
|
|
37
|
+
|
|
38
|
+
- o ponto em que a cabeça mais tomba ou mais se afasta do centro;
|
|
39
|
+
- o gesto mais largo (mão que sai para o lado, objeto levantado);
|
|
40
|
+
- as trocas de tomada (o rosto muda de lugar em cada uma).
|
|
41
|
+
|
|
42
|
+
Depois marque as **regiões obrigatórias** de cada trecho: a cabeça inteira e o rosto, sempre; as mãos, o
|
|
43
|
+
objeto mostrado ou a postura, quando carregam informação ("olha esse pote", mão contando nos dedos, o celular
|
|
44
|
+
virado para a câmera). Nenhum recorte, moldura ou peça pode cortar uma região obrigatória.
|
|
45
|
+
|
|
46
|
+
O build ajuda a conferir: nos blocos com `"acompanhar": true` ele avisa quando a cabeça sai do quadro; com o
|
|
47
|
+
`assets/maos.json` (`ferramentas/rastrear_maos.py` do projeto) ele avisa, com o intervalo, quando uma mão que a
|
|
48
|
+
gravação mostra sai do quadro da moldura ou da tela por 0,2 s ou mais. O aviso não sabe se a mão mostra algo:
|
|
49
|
+
decida você (se mostra, aumente o quadro, diminua o zoom, use tela cheia ou `contida`).
|
|
50
|
+
|
|
51
|
+
O meio do quadro não é, necessariamente, onde a pessoa está. Mire o rosto no centro da área disponível, sem
|
|
52
|
+
perseguir cada micromovimento.
|
|
53
|
+
|
|
54
|
+
## Os jeitos de mostrar a pessoa
|
|
55
|
+
|
|
56
|
+
| cena | o que aparece | quando usar |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `tela_cheia` | a pessoa ocupando a tela, zoom leve (1,08 a 1,12) com o rosto centralizado | gancho, opinião, história, desejo, chamada, demonstração feita com o corpo. O rosto vende. |
|
|
59
|
+
| `prova` | a prova em tela cheia: a própria gravação da tela (sem zoom) ou um print/vídeo (`arquivo`, a partir do segundo `inicio`), com rótulo em cima e zoom que anda até o que importa | tela do app, iPad, painel, página, print. É a prova real. |
|
|
60
|
+
| `moldura` | a pessoa num quadro arredondado embaixo e o papel quadriculado atrás (ou o próprio vídeo desfocado, `"fundo": "desfocado"`); a animação ocupa o alto | explicação que divide a tela: lista, passos, causa e efeito, diagrama, celular com notificação |
|
|
61
|
+
| `tela_verde` | a pessoa recortada num canto, com contorno branco, na frente de uma imagem ou vídeo (`fundo`) | comentário sobre algo que precisa ficar grande atrás dela: notícia, página, vídeo, produto |
|
|
62
|
+
| planos (2,5D) | a pessoa recortada no meio, uma palavra em parte atrás do corpo, um objeto à frente | palavra forte, lançamento, autoridade, explicação curta. Só com o teste de recorte aprovado. Seção "Composição em planos" |
|
|
63
|
+
| `contida` | a gravação inteira dentro da tela, com margem, sobre ela mesma desfocada (ou o papel, ou uma cor) | quando a região obrigatória não cabe no recorte (seção "Quando não cabe"), gravação em pé num 16:9, 4:5 ou 1:1 |
|
|
64
|
+
| `comparar` | dois arquivos (ou dois trechos) lado a lado ou alternando, na mesma escala e na mesma velocidade, com rótulos literais | antes e depois honesto, duas versões, duas soluções (seção "Comparar") |
|
|
65
|
+
|
|
66
|
+
## Regras de decisão
|
|
67
|
+
|
|
68
|
+
Tiradas das edições aprovadas. Siga na ordem.
|
|
69
|
+
|
|
70
|
+
1. **Comece em tela cheia.** Gancho e chamada ficam em tela cheia. O rosto prende e convence. Todo efeito
|
|
71
|
+
começa e termina com a gravação cheia na tela.
|
|
72
|
+
2. **Prova real em tela cheia, com rótulo em cima.** Se a gravação mostra a tela do app ou o iPad, esse
|
|
73
|
+
trecho é `prova` sem zoom: a prova aparece inteira. Print ou vídeo de tela da pessoa entra como `prova` com
|
|
74
|
+
`arquivo`. O rótulo diz o que é ("Tela do app", "Pedido real"), curto. Painel pequeno e ilegível não
|
|
75
|
+
prova nada: se a prova não se lê no celular, ela precisa de mais área.
|
|
76
|
+
3. **Moldura só quando a câmera volta pro rosto.** Moldura em cima da prova esconde a prova. Ela entra quando
|
|
77
|
+
a pessoa volta a falar para a câmera e a explicação precisa de espaço.
|
|
78
|
+
4. **Quando encolher as duas coisas deixa tudo ilegível, a demonstração fica com a tela toda** e a voz conduz.
|
|
79
|
+
A pessoa volta depois.
|
|
80
|
+
5. **A moldura entra e sai no corte.** O `build.py` encosta a borda do bloco no corte mais perto (até 0,35 s) e
|
|
81
|
+
avisa. A troca no corte some no salto da imagem. Se não tem corte perto, a saída volta animando em 0,55 s.
|
|
82
|
+
6. **Moldura de 4 a 12 s.** Mais que isso cansa. Nada de moldura decorativa o vídeo inteiro, nem pessoa pequena
|
|
83
|
+
num canto por padrão. Divida com um trecho de tela cheia no meio.
|
|
84
|
+
7. **Na moldura a legenda sai.** Quem explica ali é a animação. A legenda volta quando volta a tela cheia.
|
|
85
|
+
(Dá para ligar com `"legenda": {"na_moldura": true}`, mas só faça se a pessoa pedir.)
|
|
86
|
+
8. **Tudo que está na moldura sai antes dela acabar.** O `build.py` corta a saída das peças 0,1 s antes do fim
|
|
87
|
+
do bloco e avisa.
|
|
88
|
+
9. **Depois de cada inserção, volte à câmera com continuidade.** Mesmo lado, mesmo tamanho de rosto de antes.
|
|
89
|
+
10. **Tela verde é para o assunto ficar grande.** Pessoa comentando uma notícia, uma página, um vídeo de outra
|
|
90
|
+
pessoa, um produto. Se a gravação já mostra a tela, não precisa. É uma coisa ou outra no mesmo trecho:
|
|
91
|
+
nunca moldura e tela verde juntas.
|
|
92
|
+
11. **Dado privado não aparece.** Nome e telefone de cliente, e-mail, senha, chave, número de pedido de outra
|
|
93
|
+
pessoa, conversa, nome de projeto na barra lateral: vai com `borrar`, com o tempo de cada caixa. O borrão é
|
|
94
|
+
queimado no arquivo (seção "Borrão"), então nem quem recebe a pasta do projeto vê o dado.
|
|
95
|
+
12. **Rosto livre.** Nada cobre olhos e boca. A legenda fica no peito, a peça pequena em cima da cabeça, a peça
|
|
96
|
+
grande na área livre da moldura. Legenda, informação e rosto em áreas separadas.
|
|
97
|
+
13. **Zona segura do Reels.** No 9:16, texto entre y 230 e 1530 e entre x 140 e 940 (a barra do topo, o botão
|
|
98
|
+
do anúncio e a coluna de curtir cobrem o resto). O modelo já respeita.
|
|
99
|
+
14. **Moldura separa, não deforma.** Contorno, sombra e uma leve inclinação separam planos. Nunca esticar,
|
|
100
|
+
espremer ou entortar a pessoa. Nada de zoom que não para nem reenquadramento agitado só para ocupar tempo.
|
|
101
|
+
15. **Visual.** `papelaria` é o padrão do modelo (no modo automático a skill usa `laranja`): papel quadriculado lilás, cartões brancos com base lilás, Montserrat 900
|
|
102
|
+
e Caveat à mão. `noite` para marca escura (azul-marinho com pontinhos, cartões brancos). `laranja` para o visual escuro dos
|
|
103
|
+
vídeos do André (fundo quase preto com grade e brilho laranja, cartões escuros com fio laranja, texto claro).
|
|
104
|
+
|
|
105
|
+
Quando uma animação grande (lista, passo a passo, diagrama, celular, fotos) cair num trecho de tela cheia e o
|
|
106
|
+
`build.py` avisar que não coube sem encostar no rosto, transforme esse trecho em moldura.
|
|
107
|
+
|
|
108
|
+
## No projeto.json
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
"blocos": [
|
|
112
|
+
{"cena": "tela_cheia", "de": 0, "ate": 14.4, "zoom": 1.1},
|
|
113
|
+
{"cena": "prova", "de": 14.4, "ate": 18.3, "rotulo": "Tela do *app*"},
|
|
114
|
+
{"cena": "moldura", "de": 18.3, "ate": 28.03},
|
|
115
|
+
{"cena": "tela_verde", "de": 28.03, "ate": 32.3, "fundo": "assets/pagina.png", "posicao": "direita"},
|
|
116
|
+
{"cena": "tela_cheia", "de": 32.3}
|
|
117
|
+
]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- `de` e `ate` em segundos do `cut.mp4` (ou a palavra, como nas animações). Buraco entre blocos vira tela cheia.
|
|
121
|
+
- `tela_cheia`: `zoom` (1,08 a 1,12), `zooms` (seção "Zoom na palavra"), `borrar`, `acompanhar` (seção
|
|
122
|
+
"Acompanhar a pessoa dentro da tomada").
|
|
123
|
+
- `prova`: `arquivo` (imagem ou vídeo em `assets/`), `inicio` (o segundo do vídeo em que a prova começa; sem
|
|
124
|
+
ele, do 0), `encaixe` (`cobrir` enche a tela; `inteiro` mostra tudo por cima de uma cópia borrada), `rotulo`,
|
|
125
|
+
`borrar` (seção "Borrão"), `zoom` (padrão 1, a prova inteira), `zooms`. A entrada da prova é um corte seco:
|
|
126
|
+
o `sons_sugeridos.json` pede um whoosh com o pico no quadro do corte, e o rótulo entra 0,62 s depois.
|
|
127
|
+
- `moldura`: `fundo` (`papel`, o padrão, ou `desfocado`: o próprio vídeo, desfocado e escurecido, atrás do
|
|
128
|
+
quadro). A caixa padrão é x 520, y 980, 400 x 540 no 9:16 e x 1080, y 120, 720 x 840 no 16:9.
|
|
129
|
+
Para mudar em todo o vídeo: `"moldura": {"caixa": [x, y, largura, altura]}` no topo do projeto. `acompanhar`
|
|
130
|
+
também vale aqui.
|
|
131
|
+
- `contida`: `fundo` (`desfocado`, o padrão; `papel`; ou uma cor, `"#1b1830"`), `margem` (px, padrão 6% do lado
|
|
132
|
+
menor), `raio`. Entra e sai no corte como a moldura.
|
|
133
|
+
- `comparar`: `a` e `b` (`arquivo`, `inicio`, `rotulo`), `modo`, `trocas`, `som` (seção "Comparar").
|
|
134
|
+
- `tela_verde`: `fundo` (imagem ou vídeo), `inicio` (do vídeo de fundo), `encaixe`, `posicao` (`direita`,
|
|
135
|
+
`esquerda`, `centro`), `altura` (0,62 no canto e 0,8 no centro, fração da tela), `contorno` (`true`).
|
|
136
|
+
- `legenda` (`true` ou `false`) em qualquer bloco força ligar ou desligar a legenda ali. Desligada num bloco, a
|
|
137
|
+
palavra que começa até 0,3 s antes dele também sai (não pisca antes da troca); a primeira palavra do bloco
|
|
138
|
+
seguinte tem legenda normal.
|
|
139
|
+
- Os campos da composição em planos e das cenas próprias estão no `LEIA.md` do modelo-projeto.
|
|
140
|
+
|
|
141
|
+
## Zoom na palavra e zoom que anda até um ponto
|
|
142
|
+
|
|
143
|
+
Nos blocos `tela_cheia` e `prova`, `zooms` é uma lista; cada zoom entra numa palavra e volta no `ate`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{"cena": "prova", "de": 12.3, "ate": 19.8,
|
|
147
|
+
"zooms": [{"em": "botão", "caixa": [0.52, 0.61, 0.30, 0.08], "ate": "clicou"},
|
|
148
|
+
{"em": "resultado", "caixa": [0.1, 0.3, 0.8, 0.3], "duracao": 0.6}]},
|
|
149
|
+
{"cena": "tela_cheia", "de": 19.8, "zooms": [{"em": "nunca", "escala": 1.3, "ate": "vendi"}]}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- `caixa` `[x, y, largura, altura]` em fração do vídeo gravado (o `cut.mp4`, de 0 a 1; na prova com `arquivo`,
|
|
153
|
+
do arquivo): a câmera anda até ela e a enquadra com uma folga (o "zoom no botão" da tela gravada). Olhe um
|
|
154
|
+
quadro para achar a caixa. `escala` troca o quanto aproxima.
|
|
155
|
+
- Sem `caixa`: punch-in no rosto, com `escala` (padrão 1,3), em 0,2 s. Com `caixa`, o zoom anda em 0,45 s
|
|
156
|
+
(`duracao`). A volta leva `duracao_volta` (padrão igual, no mínimo 0,35 s).
|
|
157
|
+
- `em` e `ate` em segundos ou a palavra. Sem `ate`, o zoom fica até o fim do bloco. Um zoom que começa antes
|
|
158
|
+
do anterior voltar vai direto de um ponto ao outro.
|
|
159
|
+
- Corte no meio do zoom continua com o zoom (no rosto, o da tomada nova). As peças e a legenda desviam do rosto
|
|
160
|
+
do jeito que ele está na tela, já com o zoom.
|
|
161
|
+
- Cada zoom pede um som (whoosh, no meio do movimento) no `sons_sugeridos.json`; `"som": false` tira.
|
|
162
|
+
|
|
163
|
+
## Borrão (dado privado)
|
|
164
|
+
|
|
165
|
+
`borrar` vale em qualquer bloco. Cada caixa é `[x, y, largura, altura]` (o bloco inteiro) ou tem o tempo
|
|
166
|
+
dela:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
"borrar": [[0.02, 0.10, 0.18, 0.80],
|
|
170
|
+
{"caixa": [0.30, 0.05, 0.40, 0.04], "de": 14.2, "ate": "projeto"}]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
- A caixa é em fração do vídeo gravado (o `cut.mp4`; na prova com `arquivo`, do arquivo), de 0 a 1. Não é
|
|
174
|
+
fração da tela: por isso o borrão acompanha o zoom e a moldura sem conta nenhuma.
|
|
175
|
+
- O borrão é **queimado no arquivo**: o build grava o `assets/cut.mp4` do projeto com as caixas borradas (o
|
|
176
|
+
original sem borrão fica no `edit/`). A prévia, o render e quem receber a pasta do projeto só veem o borrão.
|
|
177
|
+
Na prova com `arquivo`, a página usa uma cópia borrada em `assets/gerado/` e o build avisa que o original
|
|
178
|
+
continua em `assets/`: tire o original da pasta antes de mandar o projeto para alguém.
|
|
179
|
+
- Cada caixa entra um quadro antes do `de` e sai um quadro depois do `ate`. Numa imagem, o borrão vale o bloco
|
|
180
|
+
todo.
|
|
181
|
+
- Coisas que aparecem e somem (um menu que abre, uma linha que muda de lugar) pedem uma caixa com o tempo de
|
|
182
|
+
cada uma. Confira no arquivo exportado, quadro a quadro nos trechos de tela, com a conferência de dado pessoal
|
|
183
|
+
de `references/revisao.md`: a folha de quadros sozinha deixa passar.
|
|
184
|
+
|
|
185
|
+
Detalhes da conta e do código: seção "Receitas", no fim desta página.
|
|
186
|
+
|
|
187
|
+
## Acompanhar a pessoa dentro da tomada
|
|
188
|
+
|
|
189
|
+
O `face_layout.json` mede o rosto por tomada: dentro de uma tomada o enquadramento fica parado. Quase sempre
|
|
190
|
+
basta. Não basta quando a pessoa anda, se inclina muito ou muda de lugar no meio da tomada, e o trecho está com
|
|
191
|
+
zoom (moldura, tela cheia a 1,15 ou mais, um punch-in): aí o rosto escorrega para a borda ou a testa é cortada.
|
|
192
|
+
|
|
193
|
+
Nesse trecho, ponha `"acompanhar": true` no bloco (vale em `tela_cheia` e `moldura`):
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{"cena": "moldura", "de": 7.07, "ate": 10.6, "acompanhar": true},
|
|
197
|
+
{"cena": "tela_cheia", "de": 14.0, "ate": 17.7, "zoom": 1.2, "acompanhar": true,
|
|
198
|
+
"zooms": [{"em": "ééé", "escala": 1.35, "ate": "cortou"}]}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
O que o build faz:
|
|
202
|
+
|
|
203
|
+
1. **Mede o rosto 10 vezes por segundo** no `cut.mp4`, com o detector YuNet da skill (o mesmo do
|
|
204
|
+
`face_layout.py`), pelo `helpers/rastrear_rosto.py`, com o Python da skill. Grava `<EDIT>/rosto_trilha.json`,
|
|
205
|
+
preso ao tempo do `cut.mp4`: refez o corte, ele mede de novo sozinho. Uns segundos por minuto de vídeo. À mão:
|
|
206
|
+
`uv run --directory "<SKILL>" python helpers/rastrear_rosto.py '<EDIT>'`.
|
|
207
|
+
2. **Suaviza.** Mediana de 5 medidas seguidas. Zona morta: o enquadramento só se mexe quando o centro anda mais de
|
|
208
|
+
3% da largura (ou o rosto muda mais de 12% de tamanho). Cada mudança vira um movimento de 0,5 s em
|
|
209
|
+
`sine.inOut`, centrado nela: o caminho do rosto na tela é contínuo, sem pulo.
|
|
210
|
+
3. **Perdeu o rosto** (mão na frente, virou de lado): segura o último ponto bom. Depois de uma perda de 0,3 s ou
|
|
211
|
+
mais, a medida nova só vale quando 2 das 3 seguintes também acham o rosto. Nunca salta para o meio da tela.
|
|
212
|
+
4. **Recomeça em cada tomada** do `cut_timeline.json`. Tomada sem rosto nenhum fica com o enquadramento dela (o
|
|
213
|
+
build avisa).
|
|
214
|
+
5. **Anima quadro a quadro**, com a conta da Receita 2 em cada quadro, fora das transições animadas (dados e laço:
|
|
215
|
+
o seek em qualquer ponto acerta). A pessoa recortada (`assets/pessoa.webm`) recebe a mesma transformação, e a
|
|
216
|
+
transição da moldura já termina no rosto acompanhado. Na moldura o tamanho do rosto é o mediano da tomada (o
|
|
217
|
+
quadro não "respira").
|
|
218
|
+
6. **Confere a cabeça** (rosto e cabelo) dentro do quadro, 10 vezes por segundo. Quando a pessoa vai para a borda
|
|
219
|
+
da gravação e o enquadramento não tem mais para onde ir, o build avisa com o intervalo: não cabe. Diminua o
|
|
220
|
+
zoom, troque para tela cheia ou use `contida` nesse trecho.
|
|
221
|
+
|
|
222
|
+
Em tela cheia a 1,08 sobra só 8% de margem: o acompanhamento aparece com zoom maior ou num punch-in. Numa cena
|
|
223
|
+
própria, use o mesmo `rosto_trilha.json` (`tomadas[].pontos`: `[t, cx, cy, largura, altura, medido]`, frações do
|
|
224
|
+
`cut.mp4`) e anime a caixa em volta do vídeo, nunca o `<video>`.
|
|
225
|
+
|
|
226
|
+
**Quando a janela muda de tamanho, lugar ou proporção**, o enquadramento de dentro é recalculado junto com a caixa
|
|
227
|
+
de fora, na mesma curva. Se só a caixa anda, o rosto desliza para fora do lugar ou a testa some no meio da troca. O
|
|
228
|
+
modelo já faz isso na moldura e na contida; numa cena própria, faça igual.
|
|
229
|
+
|
|
230
|
+
## Quando não cabe
|
|
231
|
+
|
|
232
|
+
Às vezes nenhuma posição mostra a região obrigatória inteira (gesto muito largo, pessoa filmada de lado, vídeo
|
|
233
|
+
horizontal indo para 9:16). Não force. Na ordem:
|
|
234
|
+
|
|
235
|
+
1. Diminua o zoom (o mínimo é o que enche a tela sem borda).
|
|
236
|
+
2. Mude o destino: tela cheia no lugar da moldura, moldura maior, outro lado.
|
|
237
|
+
3. Mostre a imagem inteira contida, com margem e um fundo de apoio: o bloco `{"cena": "contida"}` (a própria
|
|
238
|
+
gravação desfocada atrás, o padrão; `"fundo": "papel"` ou uma cor).
|
|
239
|
+
|
|
240
|
+
**Vídeo gravado em pé que vai sair em 16:9** é o caso mais comum de "não cabe": o corte guarda só uma faixa da
|
|
241
|
+
altura (uns 32%) e amplia; a pessoa aparece em close, só a cabeça, e na moldura 16:9 ainda mais perto. O
|
|
242
|
+
`build.py` avisa. Antes de montar, proponha o 9:16; se o 16:9 for obrigatório, use a `contida` (item 3) nos
|
|
243
|
+
trechos em que o corpo ou as mãos importam. O build enquadra o rosto pelo retângulo que o vídeo ocupa de verdade
|
|
244
|
+
dentro da tela (um corte em pé num 16:9, 4:5 ou 1:1 passa da tela em cima e embaixo), então o rosto não se perde. Na moldura 16:9 a legenda (quando ligada com `na_moldura`) fica na
|
|
245
|
+
área livre ao lado do quadro, sem atravessar a borda dele.
|
|
246
|
+
|
|
247
|
+
Nunca esprema a largura da pessoa para caber. Nunca deixe faixa vazia ou preta fora da imagem.
|
|
248
|
+
|
|
249
|
+
A conta para encher a tela sem distorcer: fonte com W x H, alvo com w x h. O fator é
|
|
250
|
+
`k = max(w / W, h / H)`. Recorte na fonte uma janela de `w / k` por `h / k`, centrada na região obrigatória e sem
|
|
251
|
+
passar das bordas do vídeo original. Se a janela está se mexendo, faça a conta de novo em todo quadro.
|
|
252
|
+
|
|
253
|
+
## Composição em planos (2,5D)
|
|
254
|
+
|
|
255
|
+
Dá presença a uma palavra ou a um objeto em volta da pessoa. É o efeito que mais parece "edição cara", e o que
|
|
256
|
+
mais fica feio quando o recorte não aguenta. Só entra com o teste de recorte aprovado (próxima seção).
|
|
257
|
+
|
|
258
|
+
A peça pronta do texto atrás da pessoa está no `references/animacao-catalogo.md`. Aqui ficam as decisões.
|
|
259
|
+
|
|
260
|
+
- **Três planos.** Fundo: o cenário original, ou um cenário calmo. Meio: a pessoa, que é o destaque. Frente: um
|
|
261
|
+
elemento de apoio, que só entra na hora em que serve.
|
|
262
|
+
- **A palavra atrás do corpo tem que ser lida.** Pode ficar em parte escondida pela pessoa, desde que sobrem
|
|
263
|
+
letras à vista para reconstruir a palavra sem esforço (a primeira letra sempre à vista e mais da metade das
|
|
264
|
+
letras inteiras). Se o corpo cobre demais quando ela se mexe, suba, desça ou troque o lado da palavra.
|
|
265
|
+
- **O objeto fica perto do que está sendo falado**, sem tampar olhos, boca e gestos: é o campo `frente` da peça
|
|
266
|
+
(`references/animacao-catalogo.md`, peça 10), num canto de baixo, do lado oposto ao rosto; o build avisa se ele
|
|
267
|
+
passar na frente do rosto.
|
|
268
|
+
- **Cada plano anda um pouco e numa medida diferente**, para revelar a profundidade: o de trás anda menos, o da
|
|
269
|
+
frente anda mais. A peça `atras_da_pessoa` já faz: o fundo (a gravação, com a pessoa junto, porque saem do mesmo
|
|
270
|
+
vídeo) se aproxima 1,5% e desliza 6 px, a palavra desliza 36 px e a `frente` (o objeto na frente da pessoa) 80 px,
|
|
271
|
+
crescendo 4%. Sombras coerentes com a luz da gravação.
|
|
272
|
+
- **Cada elemento entra numa palavra**, e só um por vez. Passada a ênfase, tudo sai e a câmera original volta.
|
|
273
|
+
Nada de pessoa recortada o vídeo inteiro.
|
|
274
|
+
- **Legenda numa faixa própria**, longe da palavra grande e da interface do Reels. Onde a palavra escreve a
|
|
275
|
+
fala, a legenda sai.
|
|
276
|
+
- **Sem recorte utilizável:** componha nas áreas livres ao lado da pessoa e não prometa texto atrás do corpo.
|
|
277
|
+
- **Nome certo na entrega:** "composição 2,5D em camadas". Não é 3D.
|
|
278
|
+
|
|
279
|
+
Na amostra, mostre o efeito entrando, a pessoa se movendo com ele na tela e o efeito saindo. No arquivo exportado,
|
|
280
|
+
confira a borda do recorte, o sincronismo com a fala e se a pessoa continua no centro.
|
|
281
|
+
|
|
282
|
+
## Portão do recorte (teste de uns 5 s)
|
|
283
|
+
|
|
284
|
+
Recortar a pessoa do fundo é caro e pode falhar no cabelo, nos dedos e no movimento. Antes de rodar o recorte
|
|
285
|
+
num trecho longo, de trocar o cenário sem contorno ou de pôr qualquer coisa atrás da pessoa, faça um teste curto
|
|
286
|
+
e mostre. Este é um ponto em que você para e espera o ok mesmo com o resto autorizado. Só siga sem mostrar se a
|
|
287
|
+
pessoa disse com todas as letras que não quer ver o teste; mesmo assim ele roda e você confere pelos critérios.
|
|
288
|
+
|
|
289
|
+
Tela verde curta com o contorno branco aprovado: o próprio trecho é o teste. Confira pelos critérios e siga.
|
|
290
|
+
|
|
291
|
+
1. **Confira se o recorte roda neste computador** antes de prometer:
|
|
292
|
+
`uv run --directory "<SKILL>" python helpers/matte.py --check`. Falhou: diga o que falta. Nada de serviço
|
|
293
|
+
pago, envio do vídeo para fora ou modelo baixado sem a pessoa autorizar.
|
|
294
|
+
2. **Escolha uns 5 s difíceis**: cabelo solto contra o fundo, mãos se mexendo, a pessoa se movendo e, se houver,
|
|
295
|
+
um objeto cruzando na frente dela.
|
|
296
|
+
3. **Recorte só esse trecho**, no tamanho de entrega e pelo mesmo caminho do final:
|
|
297
|
+
`python3 ferramentas/pessoa_recortada.py --edit '<EDIT>' --de 12.0 --ate 17.0`
|
|
298
|
+
4. **Olhe a borda, não só se o fundo sumiu.** Monte a pessoa em cima de um fundo branco, de um preto e da camada
|
|
299
|
+
que vai passar por trás. Para os dois primeiros:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
ffmpeg -f lavfi -i color=white:s=1080x1920:d=5 -f lavfi -i color=black:s=1080x1920:d=5 \
|
|
303
|
+
-c:v libvpx-vp9 -i assets/pessoa.webm \
|
|
304
|
+
-filter_complex "[2:v]split[p1][p2];[0:v][p1]overlay=shortest=1[a];[1:v][p2]overlay=shortest=1[b];[a][b]hstack" \
|
|
305
|
+
-c:v libx264 -pix_fmt yuv420p quadros/teste_recorte.mp4
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
A terceira é a própria amostra no estúdio. Toque as três em velocidade normal e depois quadro a quadro
|
|
309
|
+
(`helpers/tira_de_quadros.py --fps 30`).
|
|
310
|
+
5. **Critérios.** Cabelo e dedos presentes. Ombros sem encolher nem sumir. Nenhum buraco no rosto ou no corpo.
|
|
311
|
+
Sem borda dupla e sem pedaço do fundo antigo grudado. O contorno fica firme: não pulsa e não deixa rastro
|
|
312
|
+
quando ela se mexe. O texto de trás desaparece atrás do corpo e volta a aparecer onde é fundo. Borda com a suavidade da imagem, sem aura clara.
|
|
313
|
+
6. **Confira a transparência abrindo o arquivo de verdade.** Nem o nome do codec nem o que o tocador mostra provam
|
|
314
|
+
que ela existe. O
|
|
315
|
+
ffmpeg só lê o alfa do VP9 com o decodificador `libvpx-vp9` pedido antes do `-i`; sem ele, o alfa sai cheio
|
|
316
|
+
e parece que não tem transparência:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
ffmpeg -hide_banner -ss 2 -c:v libvpx-vp9 -i assets/pessoa.webm -frames:v 1 \
|
|
320
|
+
-vf "alphaextract,signalstats,metadata=print:key=lavfi.signalstats.YMIN,metadata=print:key=lavfi.signalstats.YMAX" \
|
|
321
|
+
-f null - 2>&1 | grep signalstats
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Tem que sair `YMIN=0` e `YMAX=255`: partes transparentes e partes cheias. Erro "Requested planes not
|
|
325
|
+
available" quer dizer que o arquivo não tem canal de transparência.
|
|
326
|
+
7. **Mostre o teste**, com o que ele tem de limite, e espere.
|
|
327
|
+
|
|
328
|
+
**Não passou:** tente uma correção localizada e explique o motivo (recortar de novo o trecho, outro lado, outro
|
|
329
|
+
trecho de 5 s). Se continuar ruim, descarte o efeito para aquela composição, diga o limite e proponha a moldura
|
|
330
|
+
com o fundo original ou uma regravação (fundo liso e sem nada parecido com a pele ou o cabelo, luz de frente).
|
|
331
|
+
Nunca disfarce com brilho, desfoque pesado ou um retângulo por cima. Recorte exigido e impossível: diga, dê a
|
|
332
|
+
alternativa e não dê a tarefa como feita.
|
|
333
|
+
|
|
334
|
+
**Passou:** recorte o resto e reaproveite. O recorte fica guardado em `<EDIT>/renders/matte` e o
|
|
335
|
+
`assets/pessoa.json` diz que trecho ele cobre. Mudar só texto ou posição não pede recorte novo. Guarde a cópia
|
|
336
|
+
com transparência (`pessoa.webm`) separada da peça final já montada.
|
|
337
|
+
|
|
338
|
+
Três coisas diferentes, que só se trocam montando de novo: um vídeo que já tem a transparência dentro (o
|
|
339
|
+
`pessoa.webm`), uma pasta de imagens PNG transparentes e um vídeo preto e branco que serve de máscara. MP4 comum (H.264) não guarda transparência. Máscara
|
|
340
|
+
geométrica (retângulo, oval) não é recorte de fundo, e você não chama de recorte.
|
|
341
|
+
|
|
342
|
+
## Comparar (antes e depois)
|
|
343
|
+
|
|
344
|
+
Mostra uma diferença de verdade, sem truque de montagem:
|
|
345
|
+
|
|
346
|
+
```json
|
|
347
|
+
{"cena": "comparar", "de": 10.6, "ate": 14.0, "modo": "alternando", "trocas": ["palavra"], "som": "igualado",
|
|
348
|
+
"a": {"arquivo": "assets/cru.mp4", "inicio": 15.0, "rotulo": "Gravação crua"},
|
|
349
|
+
"b": {"arquivo": "corte", "inicio": 10.6, "rotulo": "Corte da skill"}}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
- **A mesma situação dos dois lados.** Antes de montar, confira que os dois pedaços mostram o mesmo momento; se não
|
|
353
|
+
mostram, diga e não monte como confronto. Dois trechos do mesmo arquivo (`inicio` diferente) ou do próprio corte
|
|
354
|
+
(`"arquivo": "corte"`) também valem.
|
|
355
|
+
- **Mesma escala e mesma velocidade.** Os dois aparecem inteiros, do mesmo tamanho, tocando juntos. Proporção ou
|
|
356
|
+
resolução diferente vem do arquivo, e o build avisa (nada é esticado nem piorado de propósito).
|
|
357
|
+
- **`modo`**: `lado_a_lado` (em linha ou empilhado, o que deixar a imagem maior; pode passar da zona segura dos
|
|
358
|
+
lados, porque não é texto) ou `alternando` (no mesmo lugar, trocando nas `trocas`, pelo menos 0,8 s cada).
|
|
359
|
+
- **Rótulo literal**, obrigatório: o que o lado é, sem opinião. "Melhor", "perfeito", "ruim" geram aviso.
|
|
360
|
+
- **Som**: `voz` (o padrão: a fala continua, os lados mudos); `a` ou `b` (só aquele lado; a voz do corte sai do
|
|
361
|
+
trecho e o build avisa a fala que fica muda: deixe esse espaço no corte); `igualado` (alternando: o som do lado
|
|
362
|
+
que está na tela, os dois no mesmo volume percebido, medido; o mais alto desce, nenhum sobe).
|
|
363
|
+
- A legenda sai no bloco. Não ponha texto por cima do detalhe que se compara.
|
|
364
|
+
- Na entrega, diga o que a comparação mostra e o que ela não prova.
|
|
365
|
+
|
|
366
|
+
## Mudar o formato de uma edição aprovada
|
|
367
|
+
|
|
368
|
+
Levar um vídeo aprovado de 9:16 para 16:9 (ou para 4:5, 1:1) sem perder nada. O projeto aceita os quatro
|
|
369
|
+
(`"formato"`: `9:16`, `16:9`, `4:5` com 1080x1350, `1:1` com 1080x1080).
|
|
370
|
+
|
|
371
|
+
1. **Versão separada.** Copie a pasta do projeto (`sala` para `sala-16x9`) e troque o `formato`. A aprovada não
|
|
372
|
+
é tocada. O nome do arquivo novo diz o formato. Gravação em pé indo para 16:9 vira close (seção "Quando não
|
|
373
|
+
cabe").
|
|
374
|
+
2. **Fica igual:** a duração, a ordem dos blocos, a fala, a oferta e os textos aprovados.
|
|
375
|
+
3. **Recomponha, não encolha.** Pessoa centralizada em cada recorte, acompanhando o movimento (seções acima).
|
|
376
|
+
Títulos e legendas reorganizados para o espaço novo. Tela e produto continuam legíveis. Imagem que não cabe
|
|
377
|
+
sem perder informação ganha outro arranjo com o mesmo material (contida, tela dividida).
|
|
378
|
+
4. **Margens da rede de destino.** Reels 9:16 é conhecida: texto em y 230 a 1530 e x 140 a 940. O 4:5 (x 100 a
|
|
379
|
+
960, y 110 a 1220) e o 1:1 (x 90 a 970, y 90 a 980) do projeto são margens folgadas, **a conferir na rede**: o
|
|
380
|
+
build avisa em todo build e a entrega diz que alguém ainda precisa conferir na rede. Para outra rede, deixe
|
|
381
|
+
margens folgadas (texto longe das bordas, sobretudo embaixo e à direita no vertical) e anote o mesmo.
|
|
382
|
+
5. **Amostras** nos pontos em que a proporção nova mais aperta e nas passagens de um arranjo para outro. Espere
|
|
383
|
+
só se a pessoa pediu para aprovar.
|
|
384
|
+
|
|
385
|
+
## Tela verde: o recorte da pessoa
|
|
386
|
+
|
|
387
|
+
O recorte vem desta skill (modelo selfie_multiclass, com fluxo óptico e filtro guiado), feito trecho por trecho
|
|
388
|
+
do `cut_timeline.json`: o filtro recomeça em cada corte e a forma da tomada anterior não vaza. Não use o
|
|
389
|
+
`npx hyperframes remove-background` para isso: ele deixa halo no cabelo e a cor do fundo antigo na borda.
|
|
390
|
+
|
|
391
|
+
1. Avise: "O recorte leva uns 3 minutos por minuto de vídeo na primeira vez" (num Mac com chip Apple livre; com
|
|
392
|
+
o computador ocupado pode passar de 10 minutos por minuto). Rode em segundo plano.
|
|
393
|
+
2. No projeto, só o trecho da tela verde:
|
|
394
|
+
`python3 ferramentas/pessoa_recortada.py --edit '<EDIT>' --de 28.03 --ate 32.3`
|
|
395
|
+
A ferramenta usa a skill anotada no `projeto.json` (`"skill"`) e diz na primeira linha qual usou; confira
|
|
396
|
+
que é esta skill (outra instalada no computador pode ser uma versão antiga). `--skill '<SKILL>'` força.
|
|
397
|
+
Sem `--de/--ate` monta o vídeo todo, o que demora bem mais. Trecho longo: passe antes pelo portão do recorte.
|
|
398
|
+
3. Sai `assets/pessoa.webm` (fundo transparente) e `assets/pessoa.json` (o trecho que ele cobre e onde a pessoa
|
|
399
|
+
encosta na borda em cada tomada). O recorte fica guardado em `<EDIT>/renders/matte`: mudar o trecho depois é
|
|
400
|
+
rápido. Tela verde fora do trecho montado: o `build.py` para e diz o comando certo.
|
|
401
|
+
4. O `cut.mp4` da pasta edit tem que ser o arquivo de verdade, nunca um atalho (a ferramenta recusa).
|
|
402
|
+
5. Erro falando de onnxruntime ou do modelo: a instalação da skill está incompleta. Peça para rodar o instalador
|
|
403
|
+
dela de novo.
|
|
404
|
+
|
|
405
|
+
O `build.py` usa o `pessoa.json` para o lado que a câmera cortou (ombro, braço) encostar na borda da tela. Se
|
|
406
|
+
ele avisar que a câmera corta o corpo do lado de dentro, troque de lado ou use `centro`.
|
|
407
|
+
|
|
408
|
+
## Passo a passo
|
|
409
|
+
|
|
410
|
+
1. Leia a fala com `python3 build.py palavras` (mostra palavras, tempos e os cortes) e marque: gancho, prova,
|
|
411
|
+
explicação, chamada. Toque os trechos e marque as regiões obrigatórias.
|
|
412
|
+
2. Conte o plano de blocos para a pessoa (regras acima; autorização em camadas).
|
|
413
|
+
3. Escreva os `blocos`. As animações de cada bloco seguem `references/animacao.md`.
|
|
414
|
+
4. Amostra do trecho mais difícil, 8 a 15 s: a troca de cena mais exigente, o gesto mais largo e a volta à
|
|
415
|
+
pessoa. `python3 build.py amostra 17.9 27.9`, depois `python3 build.py hf lint` e `python3 build.py hf check`.
|
|
416
|
+
5. Abra no estúdio (`references/estudio.md`). Sem render. Toque com som no tamanho do celular e passe a agulha
|
|
417
|
+
quadro a quadro em cada troca.
|
|
418
|
+
6. Com a amostra certa: `python3 build.py completo`, `check`, estúdio, e o render só no fim (`--quality delivery`).
|
|
419
|
+
7. Confira o arquivo exportado nas trocas, com a tira de quadros a 30 qps.
|
|
420
|
+
|
|
421
|
+
## O que conferir (tocando, e depois no arquivo exportado)
|
|
422
|
+
|
|
423
|
+
Vários quadros bonitos podem esconder um caminho ruim entre eles. Toque primeiro; depois olhe as passagens em
|
|
424
|
+
sequência densa de quadros. Anote o intervalo que você olhou.
|
|
425
|
+
|
|
426
|
+
- **Em qualquer momento:** a cabeça e os gestos que importam cabem. O rosto não salta de lugar na troca. A voz
|
|
427
|
+
continua casada com a boca.
|
|
428
|
+
- **Moldura:** o rosto inteiro dentro do quadro, olhando para dentro dele, sem mostrar só o peito; o papel
|
|
429
|
+
quadriculado (ou o vídeo desfocado) atrás; a borda lilás só depois que o quadro fechou; nenhuma peça na frente
|
|
430
|
+
do rosto enquanto o quadro fecha; a troca acontecendo no corte.
|
|
431
|
+
- **Tela cheia:** legenda no peito, sem tocar no queixo; peça em cima da cabeça sem cortar a testa.
|
|
432
|
+
- **Prova:** o rótulo legível, o dado privado borrado, a prova inteira à vista e legível no celular.
|
|
433
|
+
- **Tela verde e planos:** borda do cabelo e das mãos sem pedaço do fundo antigo; nada do cenário grudado na
|
|
434
|
+
pessoa (estante, banco do carro); o lado cortado encostado na borda; o fundo trocando no segundo certo; a
|
|
435
|
+
palavra atrás do corpo legível enquanto a pessoa se mexe; a frente sem tampar o rosto.
|
|
436
|
+
- **Acompanhar:** o rosto no lugar do começo ao fim da tomada, sem tremer nem dar pulo; nenhum aviso de cabeça
|
|
437
|
+
fora do quadro sem resposta.
|
|
438
|
+
- **Contida e comparar:** a gravação inteira à vista, com margem igual; os dois lados do mesmo tamanho, no mesmo
|
|
439
|
+
momento, com o rótulo certo; o som de um lado só (ou os dois no mesmo volume).
|
|
440
|
+
- Nada cortado na borda da tela, nada fora da zona segura, nenhuma faixa vazia.
|
|
441
|
+
|
|
442
|
+
## Pegadinhas que já custaram retrabalho
|
|
443
|
+
|
|
444
|
+
- **Corte dentro da transição da moldura usa o enquadramento da moldura.** Se a câmera troca de tomada enquanto o
|
|
445
|
+
quadro ainda está fechando, o `tl.set` de tela cheia vence a animação e a moldura mostra o peito. O modelo já
|
|
446
|
+
trata; se escrever à mão, cada corte usa o enquadramento do bloco onde ele cai.
|
|
447
|
+
- **Corte arredondado pega o rosto da tomada errada.** O tempo do corte com 3 casas (21,933) fica antes do
|
|
448
|
+
começo do trecho novo (21,9333). O modelo procura o rosto com 2 ms de folga para o lado da tomada nova.
|
|
449
|
+
- **Anime clip-path e transform, nunca left/top/width/height.** A moldura é um `clip-path: inset(...)` no
|
|
450
|
+
`#frame` do tamanho da tela e um `x, y, scale` no `#inner`. left/top travam no pixel inteiro e o lint reclama.
|
|
451
|
+
- **Vídeo com tempo não se anima.** O `<video>` com `data-start` fica parado; o que mexe é a caixa em volta
|
|
452
|
+
(`#inner`, `.pw`, `.pw2`). E nunca ponha `data-start` numa caixa que tem um `<video data-start>` dentro.
|
|
453
|
+
- **Estado do quadro 0 com um fromTo curto**, não com `tl.set(..., 0)`: o set em 0 pode sumir quando o seek
|
|
454
|
+
volta ao começo.
|
|
455
|
+
- **Recorte feito sem o cut_timeline** carrega a forma da tomada anterior por uns 4 quadros depois de cada corte.
|
|
456
|
+
Rode sempre pelo `pessoa_recortada.py` (ele usa o timeline).
|
|
457
|
+
- **Tela verde precisa do mesmo tempo do corte.** O `pessoa.webm` tem os mesmos quadros do `cut.mp4`; o bloco
|
|
458
|
+
usa `data-media-start` igual ao início do bloco. Cortou de novo? Rode o recorte de novo.
|
|
459
|
+
- **Alfa do VP9 no ffmpeg:** sem `-c:v libvpx-vp9` antes do `-i`, o ffmpeg lê o `pessoa.webm` sem transparência.
|
|
460
|
+
- **O estúdio pode piscar a camada de baixo numa emenda.** No arquivo exportado não aparece. O arquivo é a
|
|
461
|
+
referência.
|
|
462
|
+
|
|
463
|
+
## Erros comuns
|
|
464
|
+
|
|
465
|
+
- Moldura em cima da prova (a prova some num quadrinho).
|
|
466
|
+
- Moldura longa demais, decorativa o vídeo inteiro, ou entrando no meio de uma frase sem corte.
|
|
467
|
+
- Legenda ligada na moldura junto com a animação (duas coisas para ler).
|
|
468
|
+
- Print com dado privado de outra pessoa sem borrão.
|
|
469
|
+
- Tela verde sem avisar que o recorte demora, ou com moldura junto.
|
|
470
|
+
- Texto atrás da pessoa sem teste de recorte, ou chamado de 3D.
|
|
471
|
+
- Enquadramento conferido num quadro parado só.
|
|
472
|
+
- Mudar de formato por cima da versão aprovada.
|
|
473
|
+
|
|
474
|
+
## Receitas: enquadramento, moldura, prova e tela verde
|
|
475
|
+
|
|
476
|
+
O `build.py` do projeto-modelo já faz tudo isto. Use esta página para entender o que ele fez, conferir um
|
|
477
|
+
quadro estranho ou escrever uma cena sob medida à mão.
|
|
478
|
+
|
|
479
|
+
### 1. Onde está o rosto
|
|
480
|
+
|
|
481
|
+
Esta skill mede o rosto com o YuNet em até 40 quadros de cada trecho do corte e grava
|
|
482
|
+
`<EDIT>/face_layout.json`:
|
|
483
|
+
|
|
484
|
+
```json
|
|
485
|
+
{"segments": [{"id": "r06", "start": 18.633333, "end": 21.933333,
|
|
486
|
+
"face": {"x0": 0.2017, "y0": 0.3629, "x1": 0.3598, "y1": 0.4864, "eyes_y": 0.4096, "mouth_y": 0.455}}]}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Coordenadas em fração do quadro do `cut.mp4` (0 a 1). Um trecho = uma tomada, então o rosto só muda de
|
|
490
|
+
lugar num corte. Trecho sem rosto (`"face": null`, gravação de tela) usa o último rosto visto.
|
|
491
|
+
|
|
492
|
+
Comando, se faltar: `uv run --directory "<SKILL>" python helpers/face_layout.py --edit-dir '<EDIT>'`.
|
|
493
|
+
Ele também imprime uma sugestão de altura para gancho, legenda e chamada.
|
|
494
|
+
|
|
495
|
+
**Pegadinha do arredondamento:** o corte em 21,933 (3 casas) cai 0,3 ms ANTES do trecho novo (21,9333) e
|
|
496
|
+
pegaria o rosto da tomada anterior. Procure o rosto com folga para o lado novo:
|
|
497
|
+
`s.start - 0.002 <= t < s.end - 0.002`.
|
|
498
|
+
|
|
499
|
+
### 2. Enquadrar pelo rosto (tela cheia e moldura)
|
|
500
|
+
|
|
501
|
+
O vídeo inteiro fica dentro de `#inner` (1080 x 1920, `transform-origin: 0 0`) e a caixa visível é o
|
|
502
|
+
`clip-path` do `#frame`. Para uma caixa `(bx, by, bw, bh)` e o rosto `(cx, cy)` = centro, `fw` = largura:
|
|
503
|
+
|
|
504
|
+
```python
|
|
505
|
+
if caixa == tela_inteira:
|
|
506
|
+
z = zoom # 1,08 a 1,12 na tela cheia; 1 na prova
|
|
507
|
+
else: # moldura: rosto com uns 40% da largura da caixa
|
|
508
|
+
z = max(0.40 * bw / (fw * W), bw / W, bh / H)
|
|
509
|
+
x = clamp(bw / 2 - z * cx * W, bw - z * W, 0) # rosto no meio da largura, sem mostrar borda preta
|
|
510
|
+
y = clamp(0.42 * bh - z * cy * H, bh - z * H, 0) # rosto a 42% da altura da caixa
|
|
511
|
+
inner = {"x": x + bx, "y": y + by, "scale": z}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Com `zoom` 1 na tela cheia o `x` trava em 0 (o vídeo já tem a largura da tela): o rosto não centraliza.
|
|
515
|
+
Por isso a tela cheia usa 1,08 a 1,12. A prova fica em 1 de propósito: a prova aparece inteira.
|
|
516
|
+
|
|
517
|
+
### 3. A moldura
|
|
518
|
+
|
|
519
|
+
```css
|
|
520
|
+
#bg{position:absolute;inset:0;opacity:0;background-color:#fffdfd;
|
|
521
|
+
background-image:linear-gradient(#e6ddf8 2px,transparent 2px),linear-gradient(90deg,#e6ddf8 2px,transparent 2px);background-size:60px 60px}
|
|
522
|
+
#borda{position:absolute;left:520px;top:980px;width:400px;height:540px;border-radius:40px;opacity:0;
|
|
523
|
+
box-shadow:0 0 0 6px #c7b7ef,0 16px 0 2px #665080,0 30px 50px rgba(53,44,64,.35)}
|
|
524
|
+
#frame{position:absolute;left:0;top:0;width:1080px;height:1920px;overflow:hidden}
|
|
525
|
+
#inner{position:absolute;left:0;top:0;width:1080px;height:1920px;transform-origin:0 0}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Ordem das camadas: `#bg` (papel), `#borda` (o aro fica por baixo do quadro e aparece em volta), `#frame`.
|
|
529
|
+
|
|
530
|
+
Entrada (no corte em 21,933 de uma amostra que começa em 17,9, então 4,033 na timeline):
|
|
531
|
+
|
|
532
|
+
```js
|
|
533
|
+
tl.set("#inner",{x:0,y:-78.2,scale:1.1},4.033); // tela cheia da tomada nova
|
|
534
|
+
tl.fromTo("#frame",{clipPath:"inset(0px 0px 0px 0px round 0px)"},
|
|
535
|
+
{clipPath:"inset(980px 160px 400px 520px round 40px)",duration:0.7,ease:"power3.inOut",immediateRender:false},4.033);
|
|
536
|
+
tl.fromTo("#inner",{x:0,y:-78.2,scale:1.1},{x:435.9,y:442.8,scale:0.9371,duration:0.7,ease:"power3.inOut",immediateRender:false},4.033);
|
|
537
|
+
tl.fromTo("#borda",{opacity:0},{opacity:1,duration:0.25,immediateRender:false},4.583); // aro só quando o quadro fechou
|
|
538
|
+
tl.fromTo("#bg",{opacity:0},{opacity:1,duration:0.6,immediateRender:false},4.033);
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
O `inset` é `top right bottom left round raio`: `inset(y, W - x - w, H - y - h, x)`. O quadro e o vídeo
|
|
542
|
+
andam juntos na mesma curva (`power3.inOut`, 0,7 s), então a pessoa "encolhe para dentro" do quadro.
|
|
543
|
+
|
|
544
|
+
Saída no corte (troca seca, o corte esconde o salto):
|
|
545
|
+
```js
|
|
546
|
+
tl.to("#bg",{opacity:0,duration:0.2,immediateRender:false},t - 0.05);
|
|
547
|
+
tl.set("#borda",{opacity:0},t);
|
|
548
|
+
tl.set("#frame",{clipPath:"inset(0px 0px 0px 0px round 0px)"},t);
|
|
549
|
+
tl.set("#inner",{/* tela cheia da tomada nova */},t);
|
|
550
|
+
```
|
|
551
|
+
Saída fora de corte: o mesmo caminho da entrada ao contrário, em 0,55 s, e o papel some 0,4 s depois.
|
|
552
|
+
|
|
553
|
+
**O que vence nos 0,7 s em que o quadro fecha: o quadro.** Peça do catálogo cuja palavra cai nesse tempo entra
|
|
554
|
+
quando ele termina de fechar (o build avisa com o tempo novo); cena própria recebe
|
|
555
|
+
`window.__cenas[...].moldura.fechada_em` e o build avisa quando ela começa antes. A peça chega uns 0,3 a 0,6 s
|
|
556
|
+
depois da palavra, o que é melhor que passar na frente do rosto ainda grande.
|
|
557
|
+
|
|
558
|
+
**Fundo desfocado** (`"fundo": "desfocado"` no bloco): o build grava `assets/gerado/cut_fundo.mp4` (o corte
|
|
559
|
+
pequeno, desfocado e sem som) e põe atrás do quadro, no tempo do corte, entrando junto com o papel. É outro
|
|
560
|
+
arquivo, então o lint não acusa mídia repetida. Painel de vidro fosco ou outro arranjo continua sendo cena
|
|
561
|
+
própria.
|
|
562
|
+
|
|
563
|
+
Cada corte dentro do bloco troca o enquadramento com um `tl.set("#inner", ...)` no quadro do corte, usando
|
|
564
|
+
a caixa do bloco onde o corte cai. **Corte no meio da transição de entrada usa a moldura** (se usar a tela
|
|
565
|
+
cheia, o set vence o tween e o quadro mostra o peito).
|
|
566
|
+
|
|
567
|
+
No 16:9 a caixa padrão é x 1080, y 120, 720 x 840 (à direita) e a área livre fica à esquerda (x 100 a 1020).
|
|
568
|
+
|
|
569
|
+
### 4. A prova
|
|
570
|
+
|
|
571
|
+
Gravação que já mostra a tela (câmera filmando o iPad): bloco `prova` sem `arquivo`, zoom 1, a imagem
|
|
572
|
+
inteira. Print ou vídeo de tela da pessoa: `arquivo`.
|
|
573
|
+
|
|
574
|
+
```html
|
|
575
|
+
<div class="pvw" id="pvw1"> <!-- caixa sem tempo: é ela que o zoom mexe -->
|
|
576
|
+
<video id="pr1" class="midia" src="assets/reel.mp4" muted playsinline data-start="10.133" data-duration="2.734"
|
|
577
|
+
data-media-start="9.9" data-track-index="41"></video>
|
|
578
|
+
</div>
|
|
579
|
+
```
|
|
580
|
+
```css
|
|
581
|
+
.midia{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover}
|
|
582
|
+
.midia.borrada{filter:blur(30px) brightness(.55)} /* encaixe "inteiro": cópia borrada atrás */
|
|
583
|
+
.midia.inteira{object-fit:contain}
|
|
584
|
+
.pvw{position:absolute;inset:0;transform-origin:0 0}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
A imagem ou o vídeo com `data-start` é um clip: o HyperFrames mostra e esconde sozinho no tempo certo. O
|
|
588
|
+
`data-media-start` é o `inicio` do bloco (e anda junto quando a amostra começa no meio da prova). O rótulo em
|
|
589
|
+
cima vem do campo `rotulo` do bloco (um `rotulo` do catálogo em y 250). O borrão não é mais uma camada por cima:
|
|
590
|
+
é queimado no arquivo (seção "Borrão").
|
|
591
|
+
|
|
592
|
+
### 5. A tela verde
|
|
593
|
+
|
|
594
|
+
**O recorte.** `python3 ferramentas/pessoa_recortada.py --edit '<EDIT>' --de 28 --ate 32.3` roda o `helpers/matte.py` desta
|
|
595
|
+
skill (selfie_multiclass em ONNX, fluxo óptico entre quadros, filtro guiado na borda, um trecho por
|
|
596
|
+
tomada do `cut_timeline.json`) e junta os recortes com a cor do `cut.mp4`:
|
|
597
|
+
|
|
598
|
+
```
|
|
599
|
+
ffmpeg -i cut.mp4 -f concat -safe 0 -i mattes.txt \
|
|
600
|
+
-filter_complex "[0:v]setpts=N/(30*TB),format=rgba[c];[1:v]setpts=N/(30*TB),format=gray,scale=1080:1920[m];[c][m]alphamerge,format=yuva420p[v]" \
|
|
601
|
+
-map "[v]" -c:v libvpx-vp9 -pix_fmt yuva420p -b:v 0 -crf 20 -auto-alt-ref 0 -metadata:s:v:0 alpha_mode=1 assets/pessoa.webm
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
O `cut.mp4` da pasta edit tem que ser o arquivo de verdade (atalho faz o matte.py ignorar o timeline e
|
|
605
|
+
recortar tudo como um trecho só, e a forma da tomada anterior vaza na seguinte). O `hyperframes
|
|
606
|
+
remove-background` não serve: deixou halo no cabelo e a faixa de luz do fundo entre a barba e o pescoço.
|
|
607
|
+
|
|
608
|
+
**A cena.** (bloco de 28,033 a 32,3 s, `posicao: "esquerda"`, pessoa que a câmera corta à esquerda)
|
|
609
|
+
```html
|
|
610
|
+
<video id="tv4" class="midia" src="assets/fundo.mp4" muted playsinline data-start="28.033" data-duration="4.267" data-media-start="0" data-track-index="1"></video>
|
|
611
|
+
<div class="pw" style="transform:translate(0px,729.6px) scale(0.62)">
|
|
612
|
+
<div class="pw2" id="pw4" style="filter:drop-shadow(8.1px 0px 0 #fff) drop-shadow(-8.1px 0px 0 #fff) drop-shadow(0px 8.1px 0 #fff)
|
|
613
|
+
drop-shadow(0px -8.1px 0 #fff) drop-shadow(5.6px 5.6px 0 #fff) (...as outras 3 diagonais...) drop-shadow(0 23px 29px rgba(0,0,0,.45))">
|
|
614
|
+
<video id="pessoa4" src="assets/pessoa.webm" muted playsinline data-start="28.033" data-duration="4.267" data-media-start="28.033" data-track-index="2"></video>
|
|
615
|
+
</div></div>
|
|
616
|
+
```
|
|
617
|
+
```js
|
|
618
|
+
tl.fromTo("#bg",{opacity:0},{opacity:1,duration:0.3,immediateRender:false},28.033);
|
|
619
|
+
tl.to("#frame",{opacity:0,duration:0.25,immediateRender:false},28.033); // o vídeo com o fundo antigo some
|
|
620
|
+
tl.fromTo("#pw4",{opacity:0,y:40},{opacity:1,y:0,duration:0.3,ease:"power3.out",immediateRender:false},28.033);
|
|
621
|
+
```
|
|
622
|
+
Da tela verde para a moldura, o quadro já nasce no lugar da moldura e aparece (0,25 s), sem passar pela tela
|
|
623
|
+
cheia. Se o `pessoa.webm` foi montado só de um trecho (`--de/--ate`), o `data-media-start` desconta o
|
|
624
|
+
`inicio` gravado no `pessoa.json`.
|
|
625
|
+
|
|
626
|
+
- `.pw` é uma caixa SEM tempo com a posição fixa (pode ter `transform` no CSS porque o GSAP não mexe nela);
|
|
627
|
+
`.pw2` é quem o GSAP anima; o `<video>` com tempo fica quieto dentro. `data-media-start` do `pessoa.webm`
|
|
628
|
+
é o início do bloco no tempo do corte (os dois vídeos têm os mesmos quadros).
|
|
629
|
+
- Posição: escala `altura` (0,62 no canto, 0,8 no centro), pés na borda de baixo (`ty = H - s*H`) e o
|
|
630
|
+
centro do rosto em 70% (direita), 30% (esquerda) ou 50% (centro) da largura.
|
|
631
|
+
- Lado cortado pela câmera: o `pessoa.json` diz em quantos quadros a pessoa encosta na esquerda e na
|
|
632
|
+
direita do quadro (`touch_left`, `touch_right`). Pessoa no canto direito que encosta na direita: a borda
|
|
633
|
+
direita do vídeo encosta na borda da tela (o ombro cortado some na borda). Encosta do lado de dentro:
|
|
634
|
+
aparece um corte reto no meio da tela, então o `build.py` avisa para trocar de lado ou usar `centro`.
|
|
635
|
+
- Contorno branco: 8 `drop-shadow` sem desfoque em volta (5 px na tela, dividido pela escala) e uma sombra
|
|
636
|
+
suave embaixo. Esconde a franja fina que o recorte deixa na borda.
|
|
637
|
+
- O fundo pode ser imagem ou vídeo; `encaixe: "inteiro"` mostra o print inteiro por cima de uma cópia
|
|
638
|
+
borrada e escura dele mesmo.
|
|
639
|
+
|
|
640
|
+
### 6. Legenda em cada cena
|
|
641
|
+
|
|
642
|
+
- Tela cheia e prova: uma linha, no máximo 3 palavras (`max_palavras`) e 14 letras (`max_letras`), nunca
|
|
643
|
+
duas na tela, quebra em vírgula, ponto ou pausa de 0,6 s. Legenda de uma palavra só que ficaria menos de
|
|
644
|
+
0,3 s na tela junta com a vizinha. Altura: 300 px abaixo do queixo, entre y 1100 e 1400 (no peito).
|
|
645
|
+
Mesma altura enquanto a diferença for menor que 40 px (sem tremida entre uma legenda e a próxima).
|
|
646
|
+
- Estilo (`legenda.estilo`): `padrao` é caixa alta, Montserrat 900 60 px branca com contorno de 10 px
|
|
647
|
+
(`-webkit-text-stroke` + `paint-order: stroke fill`); `discreta` é menor (44 px), sem caixa alta, peso 700,
|
|
648
|
+
num fundo escuro leve arredondado, até 22 letras. Legenda escrita à mão (papelaria), manchete ou impacto é
|
|
649
|
+
cena própria.
|
|
650
|
+
- Moldura: sem legenda (a animação explica). Palavra a menos de 0,3 s antes da troca também sai, para a legenda
|
|
651
|
+
não piscar antes da transição. Com `na_moldura`, no 9:16 a legenda fica logo acima do quadro e no 16:9 na
|
|
652
|
+
área livre ao lado dele, sem atravessar a borda.
|
|
653
|
+
- Tela verde: legenda no peito da pessoa recortada.
|
|
654
|
+
- Peça ocupando o lugar da legenda: a legenda desce para 1420 ou sobe para 1120.
|