primocode 10.9.1 → 10.10.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.
@@ -22,59 +22,58 @@ Não faça nada disto, em nenhum vídeo:
22
22
 
23
23
  ## O que separa motion bom de slide animado
24
24
 
25
- **A câmera existe.** Zoom, pan e dolly são da CENA, não do elemento. Um zoom
26
- lento de 1.0 para 1.08 ao longo de uma cena dá vida a um quadro parado — e
27
- quase nenhum vídeo automático faz isso.
25
+ **A câmera existe.** Um zoom lento de 1.0 para 1.08 na cena inteira dá vida a
26
+ um quadro parado.
28
27
 
29
28
  **Nada entra do nada.** Um elemento entra vindo de algum lugar (de baixo, de
30
- trás, de fora do quadro), com `saida` ou `elastico` na suavização. Movimento
29
+ trás, de fora do quadro), com `spring` do Remotion ou easing de saída. Movimento
31
30
  linear é a assinatura da máquina: no mundo físico nada começa e para na mesma
32
31
  velocidade.
33
32
 
34
- **Profundidade.** Camadas que se movem em velocidades diferentes (parallax)
35
- custam duas linhas e mudam a cena inteira: fundo devagar, meio médio, frente
36
- rápido. Com `perspectiva` na cena, `rotacaoX`/`rotacaoY`/`z` viram 3D de
37
- verdade.
33
+ **Profundidade.** Parallax (fundo devagar, frente rápido); `perspective` com
34
+ `rotateX`/`translateZ`, ou three, para 3D de verdade.
38
35
 
39
- **Ritmo.** Cena de informação simples: 1,5 a 2,5s. Cena com frase para ler: 3
40
- a 4s. Fecho: 2s. Variar a duração é o que cria ritmo; repetir cria sono.
36
+ **Ritmo.** Informação simples 1,5–2,5 s; frase para ler 3–4 s; fecho 2 s.
41
37
 
42
38
  **Silêncio visual.** Um quadro com uma frase e mais nada vale mais que um com
43
39
  seis elementos. Espaço vazio é composição, não desperdício.
44
40
 
45
- ## Motion é contínuo, não uma tela por ideia
46
-
47
- Slide troca de tela. Motion é UM plano onde o mesmo objeto VIRA o próximo: a
48
- bolinha acende um fogo, se deforma em foguete, mergulha no celular e vira o
49
- ícone; o cursor gira e clica; o ícone salta e cobre a tela com o app dentro.
50
-
51
- Em vídeo de produto, anúncio e vinheta, escreva **uma cena de 8 a 15 s** no
52
- `estudio_plano`, não uma cena por frase:
53
-
54
- - **`forma: "traco"`**: forma livre por `caminho` (`d` de SVG, caixa 0 0 100
55
- 100, M/L/C/Q/Z). `caminho` e `cor` animam:
56
- `"caminho": [{"t":1.6,"v":BOLA},{"t":2.5,"v":FOGUETE,"e":"elastico"}]`.
57
- - **A troca é no mesmo lugar e instante**: o foguete some onde o ícone nasce; o
58
- app nasce do tamanho e da COR do ícone.
59
-
60
- Sem imagem é o padrão (foto só se pedirem). Decida `clima`, o impacto (`destaque`, ≤1 em 3 partes), o
61
- respiro e o `estilo` deste roteiro: `gerativo`, `fluido`, `impacto`, `vox`, `marca`, `lancamento`; vazio, gira.
62
- `hibrido` só com imagem pedida. Leia os avisos da revisão.
41
+ ## O caminho: você escreve cada cena
42
+
43
+ Motion nesse nível não sai de molde: cada cena é UMA ideia desenhada para a
44
+ fala — a interface do produto montando, o número que cresce, o objeto em 3D,
45
+ o gráfico que mostra a ideia, a palavra gigante que se transforma. Quem
46
+ desenha é você, em React.
47
+
48
+ 1. `estudio_projeto` (criar). A marca tem site? `estudio_site` mede cores e fontes.
49
+ 2. `estudio_midia acao:"estilos"`: monte a identidade pelo assunto em
50
+ `roteiro.estiloVisual` (humor, paleta, display, texto…). Um vídeo, uma
51
+ identidade: 2 chãos, 1 acento, 2 fontes.
52
+ 3. `estudio_narrar` com o roteiro: os tempos MEDIDOS de cada fala.
53
+ 4. Para cada parte, `write_file` com `path:"componentes/<nome>.jsx"`:
54
+ `export default function Cena({ el, t, fps })`, `t` em segundos desde o
55
+ começo da parte. Em `el.dados`: `titulo`, `fala`, `palavras` (cada uma com
56
+ o seu `t`, para entrar junto com a voz), `duracao`, `cores` {fundo, texto,
57
+ acento}, `fontes`, `largura`, `altura`. Imports só de react, remotion,
58
+ @remotion/*, three. Cor e fonte vêm de `el.dados`, nunca inventadas na cena.
59
+ 5. `estudio_plano` com o roteiro: `estiloVisual` e, em cada parte,
60
+ `componente:"componentes/<nome>.jsx"`. Voltou `cenasQuebradas`? Conserte o
61
+ arquivo e mande o roteiro de novo.
62
+ 6. `estudio_render`. A voz, a trilha, os sons e o fundo são do Estúdio.
63
+
64
+ Parte sem `componente` cai no gerativo (a tipografia anima sozinha): é a
65
+ reserva, não o objetivo. Sem imagem é o padrão (foto só se pedirem).
63
66
 
64
67
  ## Cor e tipo
65
68
 
66
- Escolha a paleta a partir do ASSUNTO, e escreva os valores. Três a cinco
67
- cores: uma dominante, uma de destaque, neutros com viés da dominante. Se a
68
- marca existe, leia o site dela com `estudio_site` e use as cores medidas —
69
- não as que você imagina que ela usa.
69
+ A paleta sai do ASSUNTO, no `estiloVisual` (um nome do cardápio ou 5 cores
70
+ suas). Se a marca existe, as cores medidas pelo `estudio_site` mandam — não
71
+ as que você imagina que ela usa.
70
72
 
71
- Duas fontes, no máximo: uma de display para o que grita, uma neutra para o
72
- que se lê. `estudio_midia acao:"fontes"` mostra um leque grande — sair do
73
- Inter/Montserrat é metade do trabalho de não parecer genérico.
73
+ Duas fontes, no máximo: display para o que grita, neutra para o que se lê.
74
74
 
75
75
  ## Antes de renderizar
76
76
 
77
- - Todo `src` aponta para arquivo que existe na pasta (baixe antes).
78
77
  - Os tempos das cenas batem com os tempos MEDIDOS da narração.
79
78
  - Nenhuma cena tem a mesma composição da anterior.
80
79
  - Leia o seu próprio plano e pergunte: em que este vídeo é diferente do
package/studio/edge.py CHANGED
@@ -204,6 +204,11 @@ def sintetizar(texto, voz_cfg=None, timeout=90):
204
204
  if r.returncode != 0 or not os.path.exists(mp3) or os.path.getsize(mp3) < 800:
205
205
  msg = (r.stderr or b"").decode("utf-8", "replace")[-200:]
206
206
  sys.stderr.write("[edge] síntese falhou: %s\n" % msg)
207
+ # 403 do Bing = edge-tts velho (13/10): atualiza em segundo plano, e a próxima fala já sai.
208
+ if "403" in msg:
209
+ threading.Thread(target=lambda: subprocess.run(
210
+ [sys.executable, "-m", "pip", "install", "--user", "--quiet", "--upgrade", "--break-system-packages", "edge-tts"],
211
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=240), daemon=True).start()
207
212
  return None, None
208
213
  with open(mp3, "rb") as fh:
209
214
  dados = fh.read()
package/studio/narrar.py CHANGED
@@ -317,6 +317,22 @@ def comando_roteiro(args):
317
317
  try:
318
318
  ps = _parte_edge(texto, v["voz"], reg["ritmo"], reg["tom"], mp3)
319
319
  except Exception as e:
320
+ # 403 do Bing: a Microsoft trocou a autenticação e o edge-tts
321
+ # desta máquina ficou velho (13/10: o 7.2.8 levava 403, o
322
+ # 7.3.0 não). Sem isto, toda narração caía na voz robótica de
323
+ # reserva quando a cota do Gemini acabava. Atualiza uma vez e
324
+ # roda de novo num processo novo (o módulo velho já carregou).
325
+ if "403" in str(e) and not os.environ.get("PRIMO_EDGE_ATUALIZADO"):
326
+ for estrategia in ESTRATEGIAS:
327
+ try:
328
+ r = subprocess.run([sys.executable] + estrategia[:3] + ["--upgrade"] + estrategia[3:],
329
+ capture_output=True, timeout=240)
330
+ if r.returncode == 0:
331
+ break
332
+ except Exception:
333
+ pass
334
+ os.environ["PRIMO_EDGE_ATUALIZADO"] = "1"
335
+ os.execv(sys.executable, [sys.executable] + sys.argv)
320
336
  return {"ok": False, "error": f"a voz falhou na parte {i + 1}: {str(e)[:200]}"}
321
337
  dur = _duracao(mp3)
322
338
  wav = Path(tmp) / f"p{i:02d}.wav"