primocode 10.15.2 → 10.17.0

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.
Files changed (245) hide show
  1. package/LICENSES/edit-ia-pro.txt +32 -0
  2. package/LICENSES/fontes-OFL.txt +476 -0
  3. package/LICENSES/hyperframes-Apache-2.0.txt +205 -0
  4. package/LICENSES/permanent-marker-Apache-2.0.txt +204 -0
  5. package/LICENSES/selfie-multiclass-Apache-2.0.txt +227 -0
  6. package/LICENSES/three-MIT.txt +23 -0
  7. package/LICENSES/video-use-MIT.txt +24 -0
  8. package/LICENSES/woven-sfx-CC0.txt +16 -0
  9. package/LICENSES/yunet-MIT.txt +21 -0
  10. package/README.md +2 -2
  11. package/bin/primocode.js +74 -9
  12. package/editor/LICENSE.md +11 -0
  13. package/editor/README.md +321 -0
  14. package/editor/SKILL.md +307 -0
  15. package/editor/THIRD_PARTY_NOTICES.md +228 -0
  16. package/editor/assets/baixar.json +591 -0
  17. package/editor/assets/fonts/anton/OFL.txt +93 -0
  18. package/editor/assets/fonts/caveat/OFL.txt +93 -0
  19. package/editor/assets/fonts/figtree/OFL.txt +93 -0
  20. package/editor/assets/fonts/fonts.json +10 -0
  21. package/editor/assets/fonts/montserrat/OFL.txt +93 -0
  22. package/editor/assets/fonts/permanentmarker/LICENSE.txt +202 -0
  23. package/editor/assets/models/SELFIE_MULTICLASS_LICENSE.txt +227 -0
  24. package/editor/assets/models/YUNET_LICENSE.txt +21 -0
  25. package/editor/assets/sfx/licencas/bass_drop.txt +32 -0
  26. package/editor/assets/sfx/licencas/cash.txt +76 -0
  27. package/editor/assets/sfx/licencas/charge.txt +31 -0
  28. package/editor/assets/sfx/licencas/click.txt +46 -0
  29. package/editor/assets/sfx/licencas/coin.txt +50 -0
  30. package/editor/assets/sfx/licencas/count.txt +47 -0
  31. package/editor/assets/sfx/licencas/data.txt +31 -0
  32. package/editor/assets/sfx/licencas/error.txt +32 -0
  33. package/editor/assets/sfx/licencas/flash.txt +31 -0
  34. package/editor/assets/sfx/licencas/gears.txt +82 -0
  35. package/editor/assets/sfx/licencas/keyboard.txt +48 -0
  36. package/editor/assets/sfx/licencas/metal_hit.txt +62 -0
  37. package/editor/assets/sfx/licencas/metal_riser.txt +61 -0
  38. package/editor/assets/sfx/licencas/mouse_click.txt +50 -0
  39. package/editor/assets/sfx/licencas/notification.txt +54 -0
  40. package/editor/assets/sfx/licencas/pop.txt +38 -0
  41. package/editor/assets/sfx/licencas/rewind.txt +32 -0
  42. package/editor/assets/sfx/licencas/rise.txt +46 -0
  43. package/editor/assets/sfx/licencas/sinteticos.txt +21 -0
  44. package/editor/assets/sfx/licencas/snap.txt +50 -0
  45. package/editor/assets/sfx/licencas/success.txt +40 -0
  46. package/editor/assets/sfx/licencas/synth_hit.txt +32 -0
  47. package/editor/assets/sfx/licencas/tick.txt +14 -0
  48. package/editor/assets/sfx/licencas/whoosh.txt +47 -0
  49. package/editor/assets/sfx/licencas/wind.txt +31 -0
  50. package/editor/assets/sfx/sfx.json +832 -0
  51. package/editor/assets/sfx/sfx_sinteticos.json +317 -0
  52. package/editor/assets/sfx/sfx_woven.json +387 -0
  53. package/editor/assets/sfx/woven/LICENCA.md +16 -0
  54. package/editor/fichas/briefing-do-video.md +45 -0
  55. package/editor/fichas/conferencia-da-amostra.md +56 -0
  56. package/editor/fichas/matriz-de-ganchos.csv +3 -0
  57. package/editor/fichas/padrao.json +16 -0
  58. package/editor/fichas/planilha-de-cenas.csv +4 -0
  59. package/editor/fichas/planilha-de-versoes.csv +4 -0
  60. package/editor/fichas/plano-em-blocos.md +32 -0
  61. package/editor/fichas/registro-de-materiais.json +27 -0
  62. package/editor/helpers/assets_ocr/ocr_vision.swift +41 -0
  63. package/editor/helpers/bordas_precisas.py +272 -0
  64. package/editor/helpers/camera_viva.py +426 -0
  65. package/editor/helpers/captions.py +601 -0
  66. package/editor/helpers/common.py +308 -0
  67. package/editor/helpers/compose_final.py +3555 -0
  68. package/editor/helpers/conferir_corte.py +234 -0
  69. package/editor/helpers/conferir_dados.py +405 -0
  70. package/editor/helpers/contact_sheet.py +282 -0
  71. package/editor/helpers/corte_por_onda.py +433 -0
  72. package/editor/helpers/corte_seco.py +595 -0
  73. package/editor/helpers/denoise.py +971 -0
  74. package/editor/helpers/efeitos.py +408 -0
  75. package/editor/helpers/efeitos_gerar.py +159 -0
  76. package/editor/helpers/elevenlabs_api.py +442 -0
  77. package/editor/helpers/face_layout.py +570 -0
  78. package/editor/helpers/fetch_images.py +423 -0
  79. package/editor/helpers/ganho_por_trecho.py +214 -0
  80. package/editor/helpers/gen_image.py +312 -0
  81. package/editor/helpers/gen_music.py +316 -0
  82. package/editor/helpers/gen_sfx.py +148 -0
  83. package/editor/helpers/grade.py +307 -0
  84. package/editor/helpers/icloud.py +119 -0
  85. package/editor/helpers/make_sfx.py +940 -0
  86. package/editor/helpers/matte.py +1342 -0
  87. package/editor/helpers/medir_referencia.py +2232 -0
  88. package/editor/helpers/mixar_trilha.py +354 -0
  89. package/editor/helpers/montar_corte.py +295 -0
  90. package/editor/helpers/motion/__init__.py +13 -0
  91. package/editor/helpers/motion/engine.py +1915 -0
  92. package/editor/helpers/motion/registry.py +510 -0
  93. package/editor/helpers/motion/render.py +665 -0
  94. package/editor/helpers/motion/templates/barra_progresso.py +370 -0
  95. package/editor/helpers/motion/templates/carimbo.py +132 -0
  96. package/editor/helpers/motion/templates/checklist.py +271 -0
  97. package/editor/helpers/motion/templates/comentario_cta.py +380 -0
  98. package/editor/helpers/motion/templates/contador.py +222 -0
  99. package/editor/helpers/motion/templates/destaque.py +263 -0
  100. package/editor/helpers/motion/templates/etiqueta_preco.py +461 -0
  101. package/editor/helpers/motion/templates/grafico_barras.py +510 -0
  102. package/editor/helpers/motion/templates/grafico_linha.py +462 -0
  103. package/editor/helpers/motion/templates/notificacao.py +266 -0
  104. package/editor/helpers/motion/templates/palavra_impacto.py +410 -0
  105. package/editor/helpers/motion/templates/passos.py +321 -0
  106. package/editor/helpers/motion/templates/riscado.py +298 -0
  107. package/editor/helpers/motion/templates/selo_garantia.py +150 -0
  108. package/editor/helpers/motion_render.py +241 -0
  109. package/editor/helpers/motion_sugerir.py +961 -0
  110. package/editor/helpers/noise_check.py +134 -0
  111. package/editor/helpers/pack_transcripts.py +223 -0
  112. package/editor/helpers/palavras_na_onda.py +176 -0
  113. package/editor/helpers/plano_sfx.py +839 -0
  114. package/editor/helpers/portao.py +427 -0
  115. package/editor/helpers/preview_server.py +1177 -0
  116. package/editor/helpers/rastrear_rosto.py +298 -0
  117. package/editor/helpers/render_cut.py +1256 -0
  118. package/editor/helpers/respiros.py +89 -0
  119. package/editor/helpers/sincronizar_cameras.py +571 -0
  120. package/editor/helpers/speech_regions.py +423 -0
  121. package/editor/helpers/style_catalog.json +231 -0
  122. package/editor/helpers/style_samples.py +246 -0
  123. package/editor/helpers/tela_verde.py +2113 -0
  124. package/editor/helpers/text_render.py +2059 -0
  125. package/editor/helpers/texto_na_tela.py +366 -0
  126. package/editor/helpers/timeline_view.py +292 -0
  127. package/editor/helpers/tira_de_quadros.py +113 -0
  128. package/editor/helpers/transcribe.py +734 -0
  129. package/editor/helpers/transcribe_batch.py +129 -0
  130. package/editor/helpers/trilhas.py +1146 -0
  131. package/editor/helpers/trilhas_humores.json +66 -0
  132. package/editor/helpers/valores.py +187 -0
  133. package/editor/helpers/verify_cut.py +820 -0
  134. package/editor/helpers/voice_levels.py +233 -0
  135. package/editor/helpers/voz_check.py +386 -0
  136. package/editor/helpers/voz_limpa.py +81 -0
  137. package/editor/helpers/watch_preview.py +372 -0
  138. package/editor/modelo-projeto/LEIA.md +402 -0
  139. package/editor/modelo-projeto/assets/fontes/OFL-Caveat.txt +93 -0
  140. package/editor/modelo-projeto/assets/fontes/OFL-JetBrainsMono.txt +93 -0
  141. package/editor/modelo-projeto/assets/fontes/OFL-Montserrat.txt +93 -0
  142. package/editor/modelo-projeto/assets/fontes/larguras.json +1 -0
  143. package/editor/modelo-projeto/assets/three/BufferGeometryUtils.js +1438 -0
  144. package/editor/modelo-projeto/assets/three/GLTFLoader.js +4895 -0
  145. package/editor/modelo-projeto/assets/three/LICENSE +21 -0
  146. package/editor/modelo-projeto/assets/three/ORIGEM.txt +17 -0
  147. package/editor/modelo-projeto/assets/three/RoomEnvironment.js +185 -0
  148. package/editor/modelo-projeto/assets/three/three.core.min.js +6 -0
  149. package/editor/modelo-projeto/assets/three/three.module.min.js +6 -0
  150. package/editor/modelo-projeto/build.py +4828 -0
  151. package/editor/modelo-projeto/compositions/cenas/2d/k2d_antes_depois.html +199 -0
  152. package/editor/modelo-projeto/compositions/cenas/2d/k2d_arquivo.html +232 -0
  153. package/editor/modelo-projeto/compositions/cenas/2d/k2d_busca.html +315 -0
  154. package/editor/modelo-projeto/compositions/cenas/2d/k2d_comando.html +304 -0
  155. package/editor/modelo-projeto/compositions/cenas/2d/k2d_conversa.html +217 -0
  156. package/editor/modelo-projeto/compositions/cenas/2d/k2d_esquema.html +289 -0
  157. package/editor/modelo-projeto/compositions/cenas/2d/k2d_medidor.html +249 -0
  158. package/editor/modelo-projeto/compositions/cenas/2d/k2d_notas.html +233 -0
  159. package/editor/modelo-projeto/compositions/cenas/3d/k3d_caminho.html +197 -0
  160. package/editor/modelo-projeto/compositions/cenas/3d/k3d_explodida.html +152 -0
  161. package/editor/modelo-projeto/compositions/cenas/3d/k3d_tela.html +167 -0
  162. package/editor/modelo-projeto/compositions/cenas/3d/k3d_volume.html +124 -0
  163. package/editor/modelo-projeto/compositions/cenas/3d/motor-three.js +728 -0
  164. package/editor/modelo-projeto/compositions/cenas/LEIA.md +177 -0
  165. package/editor/modelo-projeto/ferramentas/medir_fontes.py +65 -0
  166. package/editor/modelo-projeto/ferramentas/pessoa_recortada.py +176 -0
  167. package/editor/modelo-projeto/ferramentas/rastrear_maos.py +189 -0
  168. package/editor/modelo-projeto/hyperframes.json +12 -0
  169. package/editor/modelo-projeto/package.json +11 -0
  170. package/editor/modelo-projeto/projeto.json +16 -0
  171. package/editor/preview/app.css +1009 -0
  172. package/editor/preview/app.js +2122 -0
  173. package/editor/preview/index.html +307 -0
  174. package/editor/pyproject.toml +23 -0
  175. package/editor/references/3d.md +236 -0
  176. package/editor/references/animacao-catalogo.md +672 -0
  177. package/editor/references/animacao.md +498 -0
  178. package/editor/references/comandos.md +92 -0
  179. package/editor/references/corte-seco-como-funciona.md +50 -0
  180. package/editor/references/corte-seco.md +88 -0
  181. package/editor/references/corte.md +290 -0
  182. package/editor/references/direcao-por-blocos.md +218 -0
  183. package/editor/references/enquadramento.md +654 -0
  184. package/editor/references/estilos-prontos.md +355 -0
  185. package/editor/references/estudio.md +100 -0
  186. package/editor/references/exemplo-eventos.json +67 -0
  187. package/editor/references/lettering.md +252 -0
  188. package/editor/references/modelos.md +494 -0
  189. package/editor/references/phase2.md +1007 -0
  190. package/editor/references/referencia-aplicar.md +203 -0
  191. package/editor/references/referencia-medir.md +375 -0
  192. package/editor/references/revisao.md +335 -0
  193. package/editor/references/som-e-trilha.md +146 -0
  194. package/editor/references/tabela-de-sons.md +130 -0
  195. package/editor/references/variacoes.md +234 -0
  196. package/editor/uv.lock +1141 -0
  197. package/lib/act.js +38 -8
  198. package/lib/app-chat.js +97 -0
  199. package/lib/catalogo.js +7 -1
  200. package/lib/chamada-torta.js +81 -0
  201. package/lib/editor-pro.js +786 -0
  202. package/lib/entrega.js +58 -0
  203. package/lib/estudio/conferencia-visual.js +76 -0
  204. package/lib/estudio/diretor.js +6 -1
  205. package/lib/estudio/exportar.js +3 -1
  206. package/lib/estudio/gosto/tela.html +1349 -0
  207. package/lib/estudio/gosto.js +305 -0
  208. package/lib/estudio/index.js +12 -1
  209. package/lib/estudio/kit-ae/base.jsx +119 -13
  210. package/lib/estudio/kit-ae/cenas.jsx +47 -15
  211. package/lib/estudio/kit-ae/guarda.jsx +274 -0
  212. package/lib/estudio/kit-ae/primitivas.jsx +180 -24
  213. package/lib/estudio/maquina-diretor.js +70 -12
  214. package/lib/estudio/maquina-foto.js +177 -0
  215. package/lib/estudio/maquina-guarda.js +207 -0
  216. package/lib/estudio/maquina-layout.js +22 -1
  217. package/lib/estudio/maquina.js +64 -11
  218. package/lib/estudio/referencias.js +1 -1
  219. package/lib/estudio/visao/visao.swift +97 -0
  220. package/lib/estudio/visao.js +60 -0
  221. package/lib/headless.js +15 -3
  222. package/lib/local/cerebro.json +285 -7
  223. package/lib/local/motor.js +5 -2
  224. package/lib/memoria-usuario.js +164 -0
  225. package/lib/nuvem.js +33 -2
  226. package/lib/passagem.js +50 -0
  227. package/lib/perigo.js +19 -11
  228. package/lib/protecao.js +134 -0
  229. package/lib/repeticao.js +1 -1
  230. package/lib/sandbox.js +57 -9
  231. package/lib/titulo-conversa.js +46 -0
  232. package/lib/tools.js +23 -4
  233. package/lib/ui.js +2 -2
  234. package/package.json +3 -2
  235. package/skills/editar-meu-video/SKILL.md +6 -2
  236. package/skills/editar-video/SKILL.md +113 -0
  237. package/studio/pessoa.py +52 -0
  238. package/voz/primo_voz/__main__.py +55 -40
  239. package/voz/primo_voz/app.py +500 -4
  240. package/voz/primo_voz/chat.html +1773 -0
  241. package/voz/primo_voz/conversa.py +0 -26
  242. package/voz/primo_voz/hud.html +8 -2
  243. package/voz/primo_voz/hud.py +129 -5
  244. package/voz/primo_voz/identidade.py +1 -1
  245. package/voz/primo_voz/painel_dados.py +134 -0
@@ -0,0 +1,355 @@
1
+ # Atalho: estilos prontos
2
+
3
+ O jeito padrão da skill é a edição sob medida no HyperFrames, revista no estúdio (SKILL.md). Este atalho é o
4
+ motor antigo, que monta o final sozinho com estilos prontos de legenda, gancho, tela dividida, tela verde,
5
+ animações de modelo, efeitos e trilha (`helpers/compose_final.py`). Use quando a pessoa pedir algo rápido e
6
+ simples ("só legenda e gancho"), quando quiser um dos estilos que ela já conhece pelo nome (painel de
7
+ pedidos: `papelaria`, `impacto`, `manchete`...) ou quando o computador não tiver o Node para o HyperFrames.
8
+
9
+ O corte é o mesmo (`references/corte.md`): corte pela onda, conferido e aprovado no estúdio. Daqui para a
10
+ frente tudo é pela conversa: não existe mais a aba Estilo nem o botão de aprovar do preview antigo. Os campos
11
+ de cada escolha estão em `references/phase2.md`.
12
+
13
+ ## Estilo
14
+
15
+ Com o corte aprovado:
16
+
17
+ 1. Pense num gancho (seção "Gancho e chamada") e gere as amostras com uma frase real do corte:
18
+ `uv run --directory '<SKILL>' python helpers/style_samples.py --edit-dir '<EDIT>' --text 'frase curta do vídeo' --hook-text 'Seu gancho *aqui*'`
19
+ As amostras já saem fora do rosto e num quadro em que a pessoa aparece.
20
+ 2. Mostre as imagens de `<EDIT>/samples/` (abra ou mande o arquivo) e, em lista numerada, 3 legendas e
21
+ 3 ganchos do catálogo (`label` e `desc` de `helpers/style_catalog.json`), com a sua recomendação.
22
+ Pergunte numa mensagem só: tipo de edição, legenda, gancho, cor de destaque, animações (sim ou não e
23
+ quantas), trilha (os humores que a biblioteca tem, veja "Trilha") e a limpeza de ruído, se o
24
+ `noise_check.py` indicou. Se ela disser "decide você", decida e conte em uma linha.
25
+ 3. Anote a escolha no `project.md`.
26
+
27
+ Tipos: `clean` (só a pessoa, tela cheia), `split_top` (imagem em cima nos trechos de prova),
28
+ `split_bottom` (imagem embaixo) e `tela_verde` (a pessoa recortada na frente e as imagens e vídeos da edição
29
+ no fundo, com a pessoa no canto esquerdo, no canto direito ou no meio; veja "Tela verde"). É um tipo ou outro:
30
+ nunca ofereça tela dividida junto com tela verde. Na tela verde, pergunte a posição (canto direito, canto
31
+ esquerdo ou centro). Se a pessoa trocar de "Imagem em cima" para "Tela verde", mantenha os inserts que já
32
+ estavam planejados: eles vão para o fundo sozinhos, sem nenhum passo a mais.
33
+ Como cada escolha vira campo: `references/phase2.md`.
34
+
35
+ ## O final com estilos prontos
36
+
37
+ 1. **Fala do corte.** Se o corte mudou depois da conferência, rode de novo o `conferir_corte.py` (`references/corte.md`, passo 6), que transcreve o `cut.mp4`.
38
+ 2. **O que já está escrito na tela** (vale para qualquer vídeo, e é obrigatório quando o bruto já tem
39
+ legenda gravada, print, painel ou motion com texto):
40
+ `uv run --directory '<SKILL>' python helpers/texto_na_tela.py --video '<EDIT>/cut.mp4' --edit-dir '<EDIT>'
41
+ --transcript '<EDIT>/transcripts/cut.json'`
42
+ - Ele diz quantos trechos já têm legenda, quantos são gráfico de tela cheia e guarda o mapa em
43
+ `texto_na_tela.json`. A legenda pula esses trechos sozinha e todos os textos desviam do que está
44
+ desenhado. No Mac ele lê as palavras (Vision); nos outros sistemas só acha as manchas de texto.
45
+ 3. **Legendas** no estilo escolhido. As palavras vêm das transcrições das fontes (com o `--prompt`
46
+ certo), já no tempo do corte:
47
+ `uv run --directory '<SKILL>' python helpers/captions.py --edit-dir '<EDIT>' --style impacto`
48
+ - Estilos que escrevem a frase palavra por palavra: `papelaria` (fundo escuro ou vídeo),
49
+ `papelaria_papel` (quando o fundo é claro) e `depoimento` (fala de outra pessoa).
50
+ - A linha `pulei N legenda(s)` mostra o que ficou de fora por já estar escrito na tela.
51
+ - Linhas `confira:` mostram onde as fontes e o corte ouviram palavras diferentes. Veja qual está
52
+ certa e, se preciso, troque: `--replace '20.8=20,8'` (pode repetir; aceita várias palavras).
53
+ - Palavra de marca errada: `--replace 'Cacto=Cakto'`. Mudou o estilo depois? Rode de novo.
54
+ - O vídeo já tinha legenda escrita (`references/corte.md`, passo 2) e a pessoa não quis a sua: pule este passo.
55
+ 4. **Imagens**, se o tipo for split ou tela verde, ou houver inserts (seção "Imagens"). Na tela verde,
56
+ planeje as imagens e vídeos como inserts `split_top` normais: eles viram o fundo (seção "Tela verde").
57
+ 5. **Animações (motion)**, se a pessoa quis animações no passo de estilo.
58
+ São textos e números que se desenham na tela: lista com check, lista riscada, passo a passo, etiqueta de
59
+ preço, contador, barra, gráfico, palavra de impacto, chamada para comentar, notificação, destaque
60
+ desenhado, carimbo e selo de garantia. Vídeo feito com IA (Higgsfield, Kling) continua entrando como insert; a animação é para texto
61
+ e número exatos, que a IA de vídeo não desenha.
62
+ Com a quantidade e o visual que ela escolheu (ex.: poucas = `motion.quantidade` 3, visual papelaria =
63
+ `motion.tema` "papelaria"), escreva `"motion": {"tema": ..., "quantidade": ..., "items": []}`
64
+ com esses valores e rode:
65
+ `uv run --directory '<SKILL>' python helpers/motion_sugerir.py --edit-dir '<EDIT>'`
66
+ - Ele acha os momentos da fala e fica com os N mais fortes, um em cada parte do vídeo: lista, "você não
67
+ precisa de...", passo a passo, preço, número, "comenta X", a oferta (grátis, liberado, bônus,
68
+ garantia: `carimbo` ou `selo_garantia`), a virada da história ("o caminho que eu descobri", "mas...":
69
+ `palavra_impacto`) e frase curta de impacto.
70
+ - **Pontos pedidos pela pessoa** ("põe uma animação em 01:33"): ponha esse ponto como item de `motion`
71
+ com a nota `PEDIDO:` e faça o que ela pediu, mesmo que troque o modelo.
72
+ - **Reescreva o texto** de `palavra_impacto` e `carimbo`: o sugeridor acha ONDE, você decide O QUE
73
+ escrever, com 1 a 3 palavras que resumem a ideia da frase (ex.: "Mas eu vou te contar o que eu fiz e
74
+ o que funciona" → "O QUE *FUNCIONA*"). Mostre a lista final (tempo, modelo, texto) para a pessoa
75
+ antes do render.
76
+ - **Quando usar:** só onde a fala pede. No máximo uma animação a cada 6 s. Vídeo sem nenhum momento
77
+ achado fica sem animação, e você diz isso.
78
+ - **Nunca em cima do rosto:** deixe `"region": "auto"` (o compose acha o rosto e desvia). Nunca no
79
+ gancho nem na chamada: comece depois do fim do gancho e termine antes da chamada.
80
+ - Para ver um modelo antes: `motion_render.py --template checklist --params '{"items": ["Acesso na hora"]}'
81
+ --out '<EDIT>/verify/motion'` e olhe o `checklist_folha.png`. `--list` mostra todos e `--describe ID`
82
+ os campos. Campos, exemplos e regras: `references/phase2.md`, seção `motion`.
83
+ - `animações: desligadas`: não escreva `motion`.
84
+ 6. **Escreva `<EDIT>/edit_data.json`** seguindo `references/phase2.md` (leia na primeira vez da
85
+ sessão). Seção que não está no arquivo fica desligada: escreva cada elemento escolhido.
86
+ **Posição:** deixe `camera.focus_y` e os `center_y` de fora. O compose acha o rosto em cada
87
+ trecho (`face_layout.py`) e põe cada texto no lugar livre mais perto do normal, sem cobrir o
88
+ rosto nem outro texto. Só use número se a pessoa pedir outra altura.
89
+ **Biblioteca de efeitos:** além dos 24 prontos (um som por nome, que repete), a pessoa pode ter uma
90
+ biblioteca com centenas de sons por categoria (`~/.editor-video/efeitos`; `efeitos.py listar` mostra).
91
+ No `sfx.events` use a categoria (`transicao`, `impacto`, `revelacao`, `interface`, `tecnologia`, `sucesso`,
92
+ `erro`, `humor`): cada evento da mesma categoria toca uma versão diferente. Afine pelo tipo com
93
+ `categoria:tipo` (`impacto:boom`, `impacto:punch`, `transicao:swish`, `transicao:swipe`, `revelacao:riser`,
94
+ `humor:boing`, `humor:boom808`, `tecnologia:laser`, `tecnologia:glitch`, `sucesso:powerup`) ou um som
95
+ exato (`humor-077`). Riser de revelação termina no `at` (o ponto forte é o fim). O relatório diz em
96
+ `layers` qual som tocou (`effect`). Pessoa pediu para tirar um som: `efeitos.py remover ID`.
97
+ **Efeitos pelo sentido:** escolha o som pelo que a fala diz, no segundo da palavra, com `sfx.events`
98
+ (venda `cash` ou `notification`, erro `error`, número `count`, revelação `bass_drop`; a tabela com os
99
+ 24 e os nomes em português está em `references/phase2.md`, seção `sfx`).
100
+ **Trilha:** use o humor ou o arquivo que ela escolheu. Se ela quis música mas não disse de onde,
101
+ pergunte. Siga a seção "Trilha" antes de escrever `music`.
102
+ **Ruído de fundo:** com o que foi combinado (`leve`, `forte` ou `desligado`), escreva `"audio": {"denoise": "leve"}` com o mesmo valor. O compose imprime
103
+ `ruído de fundo: leve (fundo de -50 dB para -58 dB)`; leia os `aviso:` dessa parte
104
+ (`references/phase2.md`, seção `audio`).
105
+ 6. **Prévia e olho:**
106
+ `uv run --directory '<SKILL>' python helpers/compose_final.py '<EDIT>/edit_data.json' --preview`
107
+ `uv run --directory '<SKILL>' python helpers/contact_sheet.py '<EDIT>/final_preview.mp4' --times 0.3 2 4.5 9 14 20 -o '<EDIT>/verify/final_preview.png'`
108
+ A prévia é só para você.
109
+ Troque os tempos: início, gancho, a entrada de cada insert, o meio de cada animação, meio e o último
110
+ segundo. Olhe e confira:
111
+ - gancho legível; nenhum texto em cima do rosto, da boca ou de outro texto;
112
+ - imagem e animação sem cobrir o rosto; nada cortado na borda; animação legível e com o texto certo;
113
+ - **nenhuma legenda ou texto que já estava no vídeo aparecendo duplicado**;
114
+ - **nenhum dado pessoal de outra pessoa na tela** (e-mail, telefone, CPF, cartão, conversa) sem borrão.
115
+
116
+ Leia cada linha `aviso:` que o compose imprimir. Texto que ele não conseguiu tirar do rosto vem
117
+ com a altura sugerida.
118
+ 7. **Final:**
119
+ `uv run --directory '<SKILL>' python helpers/compose_final.py '<EDIT>/edit_data.json'`
120
+ Confira `<EDIT>/verify/final_report.json`: duração igual à do corte, loudness perto de -14,
121
+ `warnings` vazio ou explicado, `face_checks` vazio. Faça a folha de quadros do `final.mp4` como
122
+ no passo 6 e olhe de novo. Em `adjustments`, cada legenda que mudou de altura ou sumiu por causa de uma
123
+ animação aparece com `"because": "motion"`.
124
+ 8. **Aprovação final.** Conte em poucas linhas o que entrou (gancho, legenda, imagens, animações, chamada,
125
+ aviso), mande o `final.mp4` e peça para assistir e dizer o que muda, com o tempo ("em 00:14 a legenda
126
+ cobre o produto").
127
+ - O tempo do final é o mesmo do corte (a duração é igual). Mudança visual: ajuste o `edit_data.json` e
128
+ renderize. Mudança de fala: volte ao `edl_manual.json` (`references/corte.md`), refaça o corte, mostre
129
+ de novo e refaça os passos 1, 2, 4, 6 e 7.
130
+ - Aprovado no chat: diga onde está o `final.mp4`, anote no `project.md` e ofereça uma variação (outro
131
+ gancho, versão mais curta: `references/variacoes.md`).
132
+
133
+ ## Gancho e chamada
134
+
135
+ **Gancho** (texto grande nos primeiros 2 a 3 s):
136
+ - No máximo 2 linhas, de 4 a 9 palavras. Se o compose avisar "gancho longo demais", encurte.
137
+ - Curiosidade ou quebra de padrão: "Olha o que eu achei pra revender", "O erro que trava suas
138
+ vendas no Instagram", "Ninguém me contou isso sobre fornecedor".
139
+ - Específico: nomeie o objeto, a situação ou o público ("Se você vende pelo Instagram, veja isso").
140
+ - Destaque de 1 a 3 palavras com asteriscos: `Você está *perdendo venda* assim`.
141
+ - Complementa a fala, não repete a primeira frase palavra por palavra.
142
+ - Sem gancho da pessoa? Ofereça 3 opções e recomende uma.
143
+
144
+ **Chamada (CTA)** no fim:
145
+ - Verbo de ação e destino: "Toque em Saiba Mais", "Clique no botão abaixo", "Chame no WhatsApp",
146
+ "Assista à aula gratuita", "Veja como funciona", "Garanta sua vaga".
147
+ - Linha de apoio (`sub`) opcional, com um fato verdadeiro: "Acesso na hora", "Aula gratuita",
148
+ "7 dias de garantia". Nada de "últimas vagas" ou "só hoje" se não for verdade.
149
+ - Combine com o que a pessoa fala no fim e com o botão do anúncio.
150
+
151
+ **Aviso de resultado:** desligado. Só entra se a pessoa pedir (`"disclaimer": {"enabled": true}`, campos em
152
+ `references/phase2.md`).
153
+
154
+ ## Imagens
155
+
156
+ - **Busca livre (padrão, sem chave):**
157
+ `uv run --directory '<SKILL>' python helpers/fetch_images.py 'leather handbag' --edit-dir '<EDIT>' --count 3 --orientation landscape`
158
+ Busque em inglês, com 1 a 3 palavras simples ("laptop", "leather handbag"). Sem resultado,
159
+ troque as palavras ou tire o `--orientation`. `landscape` para split e pip, `portrait` para
160
+ `full`. As imagens vão para `<EDIT>/assets/`, com autor e licença em `assets/credits.json`.
161
+ Abra e olhe cada imagem antes de usar: descarte marca d'água, texto, logo, pessoa famosa e
162
+ baixa qualidade. Prefira licença sem atribuição obrigatória; se usar uma que pede crédito,
163
+ avise que ele vai no texto do post.
164
+ - **Pexels:** o mesmo comando com `--source pexels`, se existir `PEXELS_API_KEY`. Sem a chave,
165
+ o helper usa o Wikimedia sozinho.
166
+ - **Arquivo da pessoa** (print, foto do produto): copie para `<EDIT>/assets/`, nunca mova.
167
+ - **Imagem com IA (opcional, paga):** só quando a busca não servir e a pessoa topar. Primeiro
168
+ `uv run --directory '<SKILL>' python helpers/gen_image.py 'descrição da cena' --edit-dir '<EDIT>' --size 1080x900 --dry-run`,
169
+ depois o mesmo sem `--dry-run`. Sem chave, o helper sai explicando. Então peça para a pessoa
170
+ colar a chave do OpenRouter aqui no chat e grave você mesmo a linha `OPENROUTER_API_KEY=...` em
171
+ `<SKILL>/.env` com a ferramenta de arquivo (ela não precisa mexer em pasta escondida). Nunca
172
+ repita a chave na conversa e nunca coloque em comando. Não gere pessoa real, marca ou produto de
173
+ terceiro. Tamanhos: split 1080x900, full 1080x1920, pip 1080x1080.
174
+
175
+ ## Tela verde
176
+
177
+ A pessoa aparece recortada, sem o fundo da gravação, na frente de uma imagem ou de um vídeo. Não precisa
178
+ de pano verde: o editor acha a pessoa sozinho em cada quadro.
179
+
180
+ **Quando oferecer** (no estilo, em uma frase, sem insistir):
181
+ - comentário sobre uma imagem, uma notícia ou um vídeo ("olha o que eu achei");
182
+ - reação a uma página, a um anúncio de concorrente ou a um print;
183
+ - mostrar um produto, um site ou um painel enquanto fala.
184
+ Vídeo em que a pessoa já mostra a tela (gravação de tela, mão apontando) não precisa: esses trechos já
185
+ aparecem como foram gravados.
186
+
187
+ **As imagens e vídeos são inserts normais.** Planeje como na tela dividida: um insert `split_top` por
188
+ momento da fala que pede prova ou imagem, com `start` e `end` no tempo do corte. Na tela verde eles não
189
+ aparecem divididos: cada um vira o fundo atrás da pessoa, no quadro exato em que começa e termina (com o
190
+ mesmo `sfx`, o mesmo `ken_burns` e os flashes de `transitions`). Não copie nada para `tela_verde.fundo`.
191
+ - `tela_verde.fundo` é só para fundo extra que não depende de um momento da fala: uma página rolando o vídeo
192
+ todo, uma cor, o próprio vídeo desfocado (`"fundo_original_desfocado": true`). Os inserts ganham dele
193
+ enquanto duram.
194
+ - Entre dois inserts (e depois do último) continua o fundo de antes: a imagem fica com o zoom lento ou
195
+ parada, o vídeo continua repetindo sem pulo.
196
+ - `full` continua cobrindo a tela toda (corte para a imagem) e `pip` continua como cartão por cima, no canto
197
+ longe do rosto.
198
+
199
+ **Pergunte de onde vêm as imagens e vídeos** (numere e recomende):
200
+ 1. arquivos da própria pessoa (print da página, print do painel, foto do produto, vídeo dela): copie para
201
+ `<EDIT>/assets/`, nunca mova;
202
+ 2. clipes gerados com IA na conta dela (Higgsfield, Kling), com o ok dela para o custo;
203
+ 3. imagens livres com o `fetch_images.py` (seção "Imagens"; `--orientation portrait` enche a tela,
204
+ `landscape` fica inteira em cima da pessoa).
205
+
206
+ **Tempo:** o recorte leva uns 3 minutos por minuto de vídeo na primeira vez (no Mac com chip Apple,
207
+ menos). Avise antes. Ele fica guardado por trecho do corte: mudar fundo, posição, textos ou cortar outra
208
+ parte do vídeo não recorta de novo o que já foi feito. Para adiantar, logo que a pessoa escolher a tela
209
+ verde rode em segundo plano:
210
+ `uv run --directory '<SKILL>' python helpers/matte.py --edit-dir '<EDIT>'`
211
+ Erro dizendo que falta o onnxruntime ou o modelo: a instalação está incompleta (rode o instalador de novo).
212
+
213
+ **Como fica:**
214
+ - Posição: `direita` ou `esquerda` (canto, a pessoa com 55% da altura da tela) ou `centro` (75%). Pessoa
215
+ gravada bem de perto fica menor no canto, para continuar parecendo canto.
216
+ - O lado que a câmera cortou (ombro, braço) encosta na borda da tela. Se o corte cair dentro da tela, só
217
+ o pedaço do corpo que encosta ali some num degradê; o braço continua inteiro. Trecho em que o rosto sai da
218
+ câmera por um lado fica encostado nesse lado, para o rosto nunca aparecer cortado no meio.
219
+ - Trecho em que a câmera corta os dois lados do corpo: no canto, a pessoa ocupa a largura toda da tela
220
+ nesse trecho, com a cabeça na mesma altura (a parte de baixo da gravação sai da tela, no máximo 20%), e
221
+ nenhum corte aparece no meio da tela. O compose avisa quais trechos; conte em uma frase, porque o tamanho da
222
+ pessoa muda nesse corte.
223
+ - Se o compose avisar que a câmera corta o corpo do lado de dentro do canto, veja se há texto na roupa ou
224
+ nos objetos que aparecem (sairia invertido). Sem texto e com o canto já escolhido pela pessoa, monte de novo
225
+ com `"espelhar": true` antes de mostrar e conte em uma frase (ela pode pedir sem espelhar). Com texto,
226
+ ofereça o que o aviso sugere: o outro canto ou o `centro`.
227
+ - Contorno branco de 8 px e sombra ligados por padrão. `zoom_cuts` e `push_in` aumentam a pessoa.
228
+ - Encaixe de cada imagem ou vídeo (`encaixe`, padrão `auto`): foto ou vídeo em pé (9:16) enche a tela
229
+ (`cobrir`); print de celular ou de painel, foto deitada e clipe quadrado aparecem inteiros e nítidos
230
+ (`inteiro`), na faixa acima da pessoa, sobre uma cópia desfocada e escura deles mesmos. Assim o valor do
231
+ print não fica atrás da pessoa nem embaixo da legenda. Print que não cabe diminui (até metade da largura).
232
+ - Clipe de vídeo com borda lisa (estúdio, cor lisa, como os clipes de IA) fica largo (até 75% da largura,
233
+ para sobrar a faixa da legenda acima da cabeça) e a borda dele continua até as beiradas: vira o cenário
234
+ atrás da pessoa, sem caixa em volta. A parte principal (onde está a maior parte dos objetos do clipe)
235
+ fica no alto; o resto passa para trás da legenda e da pessoa. Quadros vazios no começo ou no fim do clipe
236
+ não aparecem sozinhos (o fundo de antes se dissolve nele enquanto os objetos entram), e um clipe que
237
+ termina encolhendo até sumir para no último quadro cheio.
238
+ - Trecho em que o `face_layout.py` não acha rosto (gravação de tela, produto na mão) aparece como foi
239
+ gravado, em tela cheia (`"sem_rosto": "original"`).
240
+ - Legenda, gancho, chamada e animações ficam fora do rosto e, quando cabe, acima da pessoa. A legenda também
241
+ foge da parte principal da imagem inteira: fica entre a imagem e a cabeça quando cabe, senão abaixo do rosto
242
+ e, sem espaço ali, por cima da parte de baixo da imagem.
243
+ Um `center_y` escrito à mão que cairia no rosto (a pessoa mudou de lugar) vai para a altura livre mais
244
+ perto, com aviso.
245
+ - Com a câmera parada (tripé), o editor aprende o cenário de cada tomada e tira do recorte o pedaço do
246
+ cenário em que o modelo ficou em dúvida (névoa, mancha clara que pisca, franja clara ou azul na borda). O
247
+ que o modelo toma por corpo com certeza e nunca viu como fundo (uma cadeira escura entre o braço e o
248
+ corpo) continua: o relatório diz em `fundo_do_cenario` se a tomada teve o cenário aprendido.
249
+ - Na folha de quadros, confira: borda do cabelo e da mão sem pedaço do fundo antigo (o primeiro quadro, que
250
+ vira capa, também), nada do cenário (estante, carro, cadeira) grudado na pessoa, e o fundo trocando no
251
+ segundo certo. Se o recorte errar muito num trecho, troque o fundo por uma cor parecida com a gravação ou
252
+ use outro tipo de edição nesse vídeo.
253
+ - Campos e exemplos: `references/phase2.md`, seção `tela_verde`.
254
+
255
+ ## Trilha
256
+
257
+ Pergunte uma vez se a pessoa quer música de fundo (no estilo, ou antes do final se a opção de
258
+ trilha veio marcada). Ela pode ter uma **biblioteca de trilhas por humor**, que fica fora da skill
259
+ (`~/.editor-video/trilhas` no Mac, `%USERPROFILE%\.editor-video\trilhas` no Windows) e não se perde
260
+ quando a skill é instalada de novo. Veja o que tem nela:
261
+ `uv run --directory '<SKILL>' python helpers/trilhas.py humores`
262
+
263
+ **Humores:** `animada` (energia, oferta, novidade), `inspiradora` (conquista, virada de vida),
264
+ `triste` (dor, problema, desabafo), `tensa` (segredo, alerta, erro que as pessoas cometem), `calma`
265
+ (explicação, tutorial, confiança), `epica` (revelação, resultado, grande virada), `divertida`
266
+ (humor, bastidor, conteúdo leve) e `luxo` (produto premium). A pessoa pode criar humores dela.
267
+
268
+ **A pessoa disse "trilha triste"** (ou "trilha animada", "põe a épica") ou escolheu um humor no
269
+ estilo: use o humor, sem gerar nada:
270
+ `"music": {"enabled": true, "mood": "triste", "volume_db": -15, "duck": true, "fade_out": 1.5}`.
271
+ - O compose pega a favorita do humor. Sem favorita, pega a que cobre o corte sem repetir e tem menos
272
+ energia na faixa da voz. Ele copia a música para `<EDIT>/assets/trilha_triste.<ext>`, anota a
273
+ escolha em `assets/trilhas_escolhidas.json` e usa a mesma nas próximas montagens desta edição.
274
+ Conte em uma linha qual entrou (a linha `trilha do humor ...` do compose diz qual e por quê).
275
+ - Trocar por outra do mesmo humor:
276
+ `uv run --directory '<SKILL>' python helpers/trilhas.py escolher --humor triste --edit-dir '<EDIT>' --trocar`
277
+ e monte de novo. Uma trilha certa: `--trilha triste-2` no lugar de `--trocar`.
278
+ - Humor vazio ou biblioteca que ainda não existe: o compose para e diz como encher. Ofereça os
279
+ caminhos abaixo. Não invente arquivo.
280
+
281
+ **Sem humor definido, sugira um pelo trecho mais forte do anúncio:** PROBLEMA pede triste ou tensa;
282
+ VIRADA, inspiradora ou épica; PROVA e RESULTADO, épica ou calma; tutorial e PASSO, calma; oferta e
283
+ CHAMADA, animada; bastidor, divertida; produto caro, luxo. É uma música só para o vídeo inteiro:
284
+ escolha pelo clima que domina, diga o porquê em uma frase e confirme.
285
+
286
+ **De onde vem a trilha.** Dê os caminhos numerados:
287
+
288
+ 1. **Da biblioteca**, pelo humor, se ela já tem trilha nele. Recomende este.
289
+ 2. **Arquivo dela**, com direito de uso (música própria ou com licença comercial). Só para este
290
+ vídeo: copie para `<EDIT>/assets/` (nunca mova) e use `"file": "assets/nome.mp3"` no `music`. Para
291
+ guardar e usar sempre, ponha na biblioteca:
292
+ `uv run --directory '<SKILL>' python helpers/trilhas.py adicionar '/caminho/da/musica.mp3' --humor animada --titulo 'Pop da oferta'`
293
+ (`--favorita` marca como a preferida do humor). O helper copia (o original não sai do lugar),
294
+ mede volume, duração e energia e anota tudo. Música que não é dela ou sem licença: não guarde.
295
+ 3. **Gerar com IA na conta ElevenLabs dela** (opcional e pago). Usa a chave e o plano dela. Para
296
+ anúncio, só com plano pago da ElevenLabs; no plano grátis o uso comercial não é permitido.
297
+ Pessoa física: Starter ou maior. Empresa: Scale, Business ou Enterprise, conforme o número de
298
+ funcionários (o `--dry-run` mostra a regra). Vale para internet, não para TV, rádio ou cinema.
299
+ Com `--biblioteca` a trilha gerada entra na biblioteca e não precisa ser gerada de novo.
300
+ 4. **Sem trilha** (padrão). Música da biblioteca do Gerenciador de Anúncios entra depois, na Meta.
301
+
302
+ Cuidar da biblioteca (sempre com o ok da pessoa):
303
+ - `trilhas.py listar` mostra as trilhas por humor, a favorita primeiro (★), com duração, volume e
304
+ energia ("cheia desde o início" ou "começa baixa e cresce aos 8 s").
305
+ - `trilhas.py favorita triste-2` marca a preferida; `--tirar` desmarca.
306
+ - `trilhas.py remover triste-2` manda para a lixeira da biblioteca (`_lixeira`), sem apagar.
307
+ `trilhas.py restaurar triste-2` traz de volta.
308
+ - `trilhas.py onde` mostra a pasta. Humor novo: `adicionar ... --humor 'Nome do humor'` (com
309
+ `--quando 'quando usar'`); nome parecido com um que existe pede `--novo-humor`.
310
+
311
+ Para gerar (caminho 3):
312
+
313
+ - Com humor, o pedido em inglês já vem pronto:
314
+ `uv run --directory '<SKILL>' python helpers/gen_music.py --humor triste --edit-dir '<EDIT>' --dry-run`
315
+ Palavras a mais entram no fim do pedido pronto: `gen_music.py 'with soft rain' --humor triste ...`. Com
316
+ `--biblioteca` cada versão também entra na biblioteca, com a origem e o pedido anotados. Sem
317
+ `--edit-dir`, a trilha tem 60 s e vai só para a biblioteca:
318
+ `uv run --directory '<SKILL>' python helpers/gen_music.py --humor animada --biblioteca --dry-run`
319
+ - Sem humor, escreva o pedido em inglês, nesta receita: instrumental, gênero, clima, faixa de bpm,
320
+ `no vocals`, `leaves room for voice`. Oferta ou UGC: `upbeat modern pop instrumental, 110-120 bpm,
321
+ positive and confident, light drums, no vocals, leaves room for voice`. Depoimento ou aula:
322
+ `calm warm acoustic instrumental, 80-90 bpm, soft piano and guitar, hopeful, no vocals, leaves
323
+ room for voice`.
324
+ - Nunca cite artista, banda, compositor, música, álbum, gravadora, filme ou marca ("estilo
325
+ Anitta", "tipo Star Wars"), nem trecho de letra. O helper recusa os nomes mais conhecidos e a
326
+ ElevenLabs recusa o resto (`bad_prompt`, com uma sugestão: mostre para a pessoa antes de usar).
327
+ - Sempre primeiro o `--dry-run`:
328
+ `uv run --directory '<SKILL>' python helpers/gen_music.py 'upbeat modern pop instrumental, 110-120 bpm, positive, no vocals, leaves room for voice' --edit-dir '<EDIT>' --dry-run`
329
+ Ele mostra a duração (o corte + 2 s; com `--biblioteca`, pelo menos 60 s), os arquivos e o custo
330
+ estimado em créditos. Conte o custo e espere o ok da pessoa. Depois rode o mesmo sem `--dry-run`.
331
+ `--variations 2` faz duas versões para ela escolher (cada uma é cobrada).
332
+ - Sem chave, o helper sai explicando. Peça para a pessoa colar a chave da ElevenLabs aqui no chat e
333
+ grave você mesmo a linha `ELEVENLABS_API_KEY=...` em `<SKILL>/.env` com a ferramenta de arquivo.
334
+ Nunca repita a chave na conversa e nunca coloque em comando.
335
+ - A trilha sai em `<EDIT>/assets/trilha_1.mp3`, com a origem em `assets/credits.json`. Nunca salve
336
+ nem copie trilha gerada para a pasta da skill. O arquivo é só para os vídeos da pessoa: não junte
337
+ trilhas ou efeitos gerados num pacote para outras pessoas, nem copie a biblioteca dela para
338
+ ninguém.
339
+ - Erro (chave inválida, sem créditos, muitas requisições, serviço fora): conte em uma frase o que a
340
+ mensagem diz e o que a pessoa precisa fazer. Não repita o comando sem mudar nada. Se a trilha foi
341
+ gerada mas não entrou na biblioteca, a mensagem traz o comando para pôr sem gerar de novo.
342
+
343
+ No `edit_data.json`, pelo humor ou por um arquivo (arquivo ganha se vierem os dois):
344
+ `"music": {"enabled": true, "mood": "triste", "volume_db": -15, "duck": true, "fade_out": 1.5}` ou
345
+ `"music": {"enabled": true, "file": "assets/trilha_1.mp3", "volume_db": -15, "duck": true, "fade_out": 1.5}`.
346
+ Com fala o tempo todo, -15 deixa a música uns 19 dB abaixo da voz: dá para ouvir sem brigar. Mais
347
+ presença: -12. Mais baixa: -18. O antigo -22 quase some. Ouça o final: a trilha não pode brigar com
348
+ a voz.
349
+
350
+ **Efeito que os 24 prontos não têm** (opcional e pago, mesma conta e chave): veja antes se algum da
351
+ tabela de efeitos (`references/phase2.md`) não serve. Se não, com o ok da pessoa:
352
+ `uv run --directory '<SKILL>' python helpers/gen_sfx.py 'soft paper page flip' --edit-dir '<EDIT>' --seconds 1 --dry-run`
353
+ e depois sem `--dry-run`. Sai `assets/sfx_<nome>.mp3` (de 0,5 a 5 s), que entra pelo caminho em
354
+ `sfx.events` (`{"at": 7.3, "name": "assets/sfx_papel.mp3"}`) ou no `sfx` de um insert.
355
+
@@ -0,0 +1,100 @@
1
+ # O estúdio do HyperFrames
2
+
3
+ A pessoa revê a edição no estúdio do HyperFrames: o player em cima e, embaixo, a linha do tempo com uma faixa
4
+ por camada (Vídeo do corte, Legenda, cada animação, cada cena, Pessoa recortada, Voz e sons), com o nome de
5
+ cada uma. Dá para arrastar a agulha e ver o segundo exato em que cada coisa entra e sai. Tudo roda no
6
+ computador dela; nada sobe para a internet.
7
+
8
+ O estúdio mostra o projeto como ele está, sem render. Mudou o `projeto.json` ou uma cena e rodou o build, ele
9
+ recarrega sozinho. Por isso o ciclo de ajuste é rápido: mexe, roda o build, ela olha. Render só no fim.
10
+
11
+ ## Abrir
12
+
13
+ Dentro do `<PROJ>`:
14
+
15
+ ```
16
+ cd '<PROJ>' && python3 build.py corte # ou amostra <início> <fim>, ou completo
17
+ python3 build.py estudio --sem-abrir
18
+ ```
19
+
20
+ O comando sobe o estúdio em segundo plano, confere que ele responde e imprime a URL completa, por exemplo
21
+ `http://127.0.0.1:3002/#project/criativo-bolsa`. Use essa URL do jeito que saiu: sem o `#project/<pasta>` o
22
+ estúdio abre vazio. Se o estúdio deste projeto já estava no ar, ele só mostra a URL de novo.
23
+
24
+ O estúdio roda o HyperFrames na versão fixa do `package.json` do projeto, a mesma do `python3 build.py hf lint`,
25
+ `hf check` e `hf render`. Um estúdio deste projeto que esteja no ar em outra versão é derrubado e sobe de novo.
26
+ Nunca chame `npx hyperframes ...` sem versão: o npx baixa a mais nova e o check e o render rodam numa versão, o
27
+ estúdio em outra.
28
+
29
+ - Porta: a primeira livre a partir de 3002, ou `--porta N`. Porta ocupada dá erro sugerindo outra.
30
+ - O estúdio continua no ar depois que o comando termina. Derrube no fim do trabalho com
31
+ `python3 build.py estudio --parar`. Ele só derruba o deste projeto (o próprio estúdio diz de que pasta é) e
32
+ confere que a porta fechou; com a máquina carregada o HyperFrames às vezes não acha o estúdio, e aí o comando
33
+ tenta de novo e, se preciso, encerra só o processo desse estúdio. Se ainda assim não fechar, ele diz a porta e
34
+ o processo. **Nunca** use `npx hyperframes preview --kill-all`: derruba os estúdios de outros projetos da
35
+ pessoa.
36
+ - Sem o Node: o comando diz que falta e que o instalador do pacote põe o Node em `~/.editor-video/node`.
37
+
38
+ ### Em cada app
39
+
40
+ - **Claude Code no app (com o painel Browser):** rode com `--sem-abrir` e abra a URL no painel Browser
41
+ (`preview_start` com a `url`). A pessoa vê o estúdio ao lado da conversa. Com o painel **escondido**, a página
42
+ não desenha o vídeo do corte (a prévia fica preta; a legenda, as peças e as miniaturas da linha do tempo
43
+ aparecem): mostre o painel e o vídeo toca normal. Não conclua nada sobre enquadramento com o painel escondido.
44
+ - **Claude Code no terminal ou Codex:** rode sem `--sem-abrir`: ele abre o navegador padrão. Ou mande a URL
45
+ para ela abrir no Chrome.
46
+ - **Safari:** evite. A pessoa recortada (texto atrás da pessoa, tela verde) é um vídeo com fundo transparente
47
+ que o Safari pode mostrar com fundo preto. Chrome ou Edge mostram certo.
48
+ - Se nada abrir, passe a URL por escrito e diga para colar no Chrome.
49
+
50
+ ## O que mostrar em cada etapa
51
+
52
+ | Etapa | Build | O que pedir para ela olhar |
53
+ |---|---|---|
54
+ | Corte | `build.py corte` | se sobrou respiro, se alguma palavra ficou mordida, se a ordem conta a história |
55
+ | Amostra | `build.py amostra <início> <fim>` (8 s em edição simples, uns 15 s com animação, uns 5 s para texto atrás da pessoa ou 3D) | se cada coisa entra na palavra, se dá para ler no celular, se nada cobre o rosto, se o estilo é esse |
56
+ | Vídeo inteiro | `build.py completo` | o vídeo do começo ao fim, com som |
57
+
58
+ Diga onde olhar ("dá o play em 00:12, é ali que entra a lista"). Antes de mostrar, confira você mesmo:
59
+ `python3 build.py hf lint` e `python3 build.py hf check` sem erro, e um snapshot ou quadros dos pontos de troca.
60
+
61
+ Os efeitos sonoros aparecem numa faixa cada um e o estúdio toca todos, desde que estejam no `projeto.json`
62
+ (`plano_sfx.py --projeto`, `references/som-e-trilha.md`). O fim parado (`segura_fim`) aparece como a faixa "Fim
63
+ parado".
64
+
65
+ ## Pedidos que chegam do estúdio
66
+
67
+ - **Por tempo** ("em 00:14 a legenda cobre o produto"): o tempo do estúdio é o tempo do corte. Ache a peça
68
+ que está ali no `projeto.json` e ajuste.
69
+ - **"Muda isso aqui"** com ela clicando num elemento: rode no `<PROJ>`
70
+ `python3 build.py hf preview --context --json --context-fields selection`
71
+ e veja o arquivo da composição (`compositions/<id>.html` é a peça `<id>` do `projeto.json`;
72
+ `compositions/cenas/...` é uma cena sob medida) e o texto do que ela selecionou. Sem seleção
73
+ (`no-selection`), peça para ela clicar no elemento e rode de novo.
74
+ - **Ela mexeu no estúdio** (arrastou, esticou, trocou um texto): o próximo build reescreve os arquivos. O
75
+ build guarda uma cópia do que foi mexido em `.mexido-no-estudio/` e avisa. Leve a mudança para o
76
+ `projeto.json` (ou para a cena) antes de rodar o build de novo, e conte que fez isso.
77
+
78
+ ## O que pisca no estúdio e não no vídeo
79
+
80
+ O estúdio toca o vídeo do corte e a pessoa recortada como dois vídeos separados. Numa emenda, no texto atrás
81
+ da pessoa ou na tela verde, uma camada pode aparecer um quadro atrasada. No render isso não acontece, porque
82
+ ele monta quadro a quadro. Se a pessoa estranhar, diga isso e mostre o trecho renderizado:
83
+ `python3 build.py hf render --quality draft --output renders/trecho.mp4` com a `amostra` daquele trecho
84
+ (uns 3 minutos por minuto de vídeo neste tipo de Mac). O arquivo renderizado é sempre a referência final.
85
+
86
+ ## Quando dá errado
87
+
88
+ - Estúdio vazio ou "projeto não encontrado": falta o `#project/<pasta>` na URL. Use a URL que o comando
89
+ imprimiu.
90
+ - `preview-not-running` no `--context`: o estúdio caiu. Rode `python3 build.py estudio` de novo.
91
+ - A mudança não aparece: confira se o build rodou sem `Erro` e se ela está na aba do projeto certo.
92
+ - Vídeo preto na prévia, com a legenda e as peças aparecendo: o painel Browser do app está escondido (mostre)
93
+ ou o navegador é o Safari (use o Chrome).
94
+ - Máquina carregada (outros agentes, render rodando): o `estudio` pode levar mais de um minuto para responder, a
95
+ primeira visita mostra a moldura vazia e o estúdio diz que "não recarregou (demorou demais)". Recarregue a
96
+ página. O render draft continua sendo a referência.
97
+ - Com um render rodando, o painel Compositions lista também as pastas `renders/work-*`: ignore, somem no fim.
98
+ - `--parar` disse que não havia estúdio, mas a porta continua ocupada: rode de novo (ele confere a porta e as
99
+ primeiras 100 portas a partir de 3002). O `.estudio.json` do projeto guarda a porta do último estúdio.
100
+ - Faixa chamada "Track N": é uma faixa com vários clipes (a legenda, por exemplo); cada clipe tem o nome dele.
@@ -0,0 +1,67 @@
1
+ [
2
+ {
3
+ "t": 0.05,
4
+ "tipo": "whoosh-grande",
5
+ "nota": "abertura: o painel entra"
6
+ },
7
+ {
8
+ "t": 1.2,
9
+ "tipo": "pop",
10
+ "nota": "título pousa (fim do crescimento)"
11
+ },
12
+ {
13
+ "t": 3.4,
14
+ "tipo": "impacto",
15
+ "nivel": "destaque",
16
+ "nota": "número grande pousa com tremida"
17
+ },
18
+ {
19
+ "t": 5.0,
20
+ "tipo": "whoosh",
21
+ "nota": "cartão desliza pra dentro (meio do deslize)"
22
+ },
23
+ {
24
+ "t": 7.64,
25
+ "tipo": "notificacao",
26
+ "forcar": true,
27
+ "nota": "notificação de venda aparece"
28
+ },
29
+ {
30
+ "t": 10.2,
31
+ "tipo": "risco",
32
+ "nota": "item riscado"
33
+ },
34
+ {
35
+ "t": 12.5,
36
+ "tipo": "digitar",
37
+ "dur": 1.2,
38
+ "nota": "texto digitado por 1,2 s"
39
+ },
40
+ {
41
+ "t": 15.0,
42
+ "tipo": "glitch",
43
+ "nota": "tela da IA liga"
44
+ },
45
+ {
46
+ "t": 18.3,
47
+ "tipo": "dinheiro",
48
+ "nivel": "discreto",
49
+ "nota": "preço aparece"
50
+ },
51
+ {
52
+ "t": 22.0,
53
+ "tipo": "revelacao",
54
+ "nota": "logo do produto"
55
+ },
56
+ {
57
+ "t": 26.4,
58
+ "som": "kit:success",
59
+ "nivel": -15,
60
+ "nota": "check final"
61
+ },
62
+ {
63
+ "t": 29.1,
64
+ "tipo": "mensagem",
65
+ "nota": "botão da chamada"
66
+ }
67
+ ]