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,50 @@
|
|
|
1
|
+
# Como o corte seco decide cada corte
|
|
2
|
+
|
|
3
|
+
## 1. Achar as pausas
|
|
4
|
+
|
|
5
|
+
- Envelope do som em janelas de 10 ms. Com `--voz`, mede no áudio só da voz. Sem ele, no áudio do próprio vídeo.
|
|
6
|
+
- Limiar de silêncio: 30 dB abaixo da fala (percentil 90 do envelope), e pelo menos 10 dB acima do fundo (percentil 5). `--limiar` força outro valor.
|
|
7
|
+
- Pausa é um trecho abaixo do limiar com pelo menos `--pausa-min` (0,25 s). A pausa depois da última fala fica intacta, porque ali costuma estar o cartão final.
|
|
8
|
+
- Se a fala e o fundo estão a menos de 40 dB de distância, o script avisa. Quase sempre é trilha já mixada.
|
|
9
|
+
|
|
10
|
+
## 2. Onde o corte pode cair dentro da pausa
|
|
11
|
+
|
|
12
|
+
- Folga de 0,06 s depois do fim da palavra e 0,07 s antes da próxima (bordas no limiar).
|
|
13
|
+
- Consoante fraca no começo da próxima palavra: a borda anda pra trás até 0,12 s enquanto o som ainda estiver acima do "som fraco" (12 dB abaixo do limiar, ou 6 dB acima do fundo, o que for maior). Esse trecho fica protegido, com mais 0,04 s de folga.
|
|
14
|
+
- Quanto sai: a pausa menos `--pausa-max` (0,15 s), arredondado pra quadro inteiro. Se não couber entre as folgas, sai menos.
|
|
15
|
+
- Começo do vídeo: sai tudo até 0,08 s (`--inicio`) antes da primeira palavra.
|
|
16
|
+
- Trava final: se o trecho escolhido tiver qualquer janela de voz acima do limiar, o corte é descartado.
|
|
17
|
+
|
|
18
|
+
## 3. Não cortar no ataque de efeito sonoro
|
|
19
|
+
|
|
20
|
+
- Com `--sfx`: cada som do plano protege do começo do som (ou 0,3 s antes do pico, o que vier depois) até 0,06 s depois do pico. Aceita o `plano_sfx.json` do `helpers/plano_sfx.py`, uma lista de eventos (`t`) ou uma lista com `peak`.
|
|
21
|
+
- Com `--voz`: onde o vídeo tem som acima do limiar e a voz não tem, é efeito. O começo desse som (até 0,10 s) fica protegido.
|
|
22
|
+
- Se o melhor lugar pega um ataque, o corte encolhe um quadro por vez até sair de cima. Se não der, a pausa fica e aparece no relatório.
|
|
23
|
+
|
|
24
|
+
## 4. Qual quadro escolher
|
|
25
|
+
|
|
26
|
+
Entre as posições possíveis, fica a de menor mudança de imagem: soma da diferença entre quadros vizinhos no trecho que sai (imagem em 96 px, cinza). Com `--sem-grafismo`, mede só nos grafismos. Assim o pulo cai com os grafismos parados e a pessoa fica sendo a única coisa que "salta", o que parece um corte normal. Empate: fica a posição mais no meio da pausa.
|
|
27
|
+
|
|
28
|
+
## 5. Montar o vídeo
|
|
29
|
+
|
|
30
|
+
- Imagem: `select` pelos números dos quadros que ficam, `setpts` refeito, x264 CRF 16 (`slow` até 3 min, `medium` acima). Um decodificador só, exato no quadro.
|
|
31
|
+
- Som: cortado em numpy nas mesmas posições (amostra = quadro × taxa ÷ fps), com micro fade de 8 ms em cada emenda.
|
|
32
|
+
- Volume: -14 LUFS em 2 passadas, sempre linear. Se o pico real passar do teto, entra um limitador com atraso compensado (não desloca o som). Depois do AAC o pico é medido de novo; se passou de -0,5 dBTP, grava outra vez com o teto mais baixo.
|
|
33
|
+
|
|
34
|
+
## 6. Conferência automática
|
|
35
|
+
|
|
36
|
+
- Duração da imagem e do som contra a soma dos trechos mantidos.
|
|
37
|
+
- Cada quadro da saída contra o quadro esperado da entrada e os vizinhos (±2). Um deslocamento de 1 quadro já aparece aqui: no teste, 2 trechos deslocados de propósito derrubaram a conta de 1657 pra 1615 quadros e o som pra 33 ms de desvio.
|
|
38
|
+
- Cada trecho de som com mais de 0,7 s contra a entrada, por correlação.
|
|
39
|
+
- Pausas acima de `--pausa-max` + 0,07 s que ficaram na saída.
|
|
40
|
+
|
|
41
|
+
## Campos do relatório (`SAIDA.corte.json`)
|
|
42
|
+
|
|
43
|
+
- `cortes`: `pausa` (começo e fim na entrada), `removido` (o que saiu), `dur`, `sobra` (silêncio que ficou), `imagem` (quanto a imagem mudava no trecho), `forcado` nos pedidos por `--cortar`.
|
|
44
|
+
- `mantidas`: pausas que ficaram e o motivo.
|
|
45
|
+
- `mapa`: `[início na entrada, fim na entrada, início na saída]` de cada trecho. Tempo novo = início na saída + (tempo antigo - início na entrada), pro trecho que contém o tempo antigo.
|
|
46
|
+
- `conferencia`: os números do item 6.
|
|
47
|
+
|
|
48
|
+
## Resultado de referência
|
|
49
|
+
|
|
50
|
+
Reel "uma IA editou" (59,73 s, 30 fps, 47 efeitos, com `--voz`, `--sfx`, `--sem-grafismo` e a tomada repetida em `--cortar`): 19 pausas cortadas + 1 corte pedido, 4,5 s fora, saída 55,23 s. Imagem e som batendo com a entrada, 1657 de 1657 quadros no lugar, desvio de som 0,1 ms, -14 LUFS.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Corte seco
|
|
2
|
+
|
|
3
|
+
O vídeo já está pronto e aprovado, mas ficou espaço entre uma fala e outra. Este passo corta o vídeo final inteiro (imagem e som no mesmo quadro), então legenda, animação e efeito continuam grudados na fala. Em cada pausa maior que 0,25 s sobra só 0,15 s de silêncio, e o vídeo começa quase em cima da primeira palavra.
|
|
4
|
+
|
|
5
|
+
É mais barato e mais seguro do que voltar, re-cortar e renderizar tudo de novo. Foi assim no reel "uma IA editou este vídeo", aprovado pelo André.
|
|
6
|
+
|
|
7
|
+
## Quando usar aqui e quando voltar pro corte (Fase 1)
|
|
8
|
+
|
|
9
|
+
| Situação | Onde resolver |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Vídeo pronto e aprovado, pausas de 0,25 a 1 s entre as frases | **Aqui** |
|
|
12
|
+
| A pessoa pediu "mais ritmo" depois de ver o vídeo final | **Aqui** |
|
|
13
|
+
| Uma tomada repetida curta que passou (até ~1 s) e não tem animação em cima | **Aqui**, com `--cortar` |
|
|
14
|
+
| O corte ainda não foi aprovado, ou ainda não tem animação | **Corte (Fase 1)**: re-corte lá. Sai mais barato e a legenda já nasce certa |
|
|
15
|
+
| Palavra comida, respiro no meio da frase, barulho, tomada repetida grande | **Corte (Fase 1)** (`bordas_precisas.py`, `conferir_corte.py`). É problema do corte de base |
|
|
16
|
+
| Quase toda frase tem pausa de mais de 1 s | **Corte (Fase 1)**: o corte de base está frouxo. Refaça lá |
|
|
17
|
+
| Uma animação longa atravessa a pausa (câmera girando, contagem, gráfico subindo) | **Corte (Fase 1)** e renderize de novo. Aqui a animação daria um pulo. Ou aceite essa pausa |
|
|
18
|
+
| Tirar mais de ~1 s num lugar com legenda ou animação em cima (frase inteira) | **Corte (Fase 1)** e remapeie os tempos (`remap_edit_data.py`). Aqui a legenda pularia |
|
|
19
|
+
| A trilha já está mixada no vídeo e não dá pra renderizar sem ela | **Corte (Fase 1)**. Com música por baixo não dá pra achar as pausas direito |
|
|
20
|
+
|
|
21
|
+
Regra do André pra pausa: o alvo é 0,12 a 0,20 s de silêncio na emenda. A partir de 0,25 s já incomoda. Nunca cortar a pessoa no meio da palavra, e nunca esticar trecho.
|
|
22
|
+
|
|
23
|
+
## Antes de rodar
|
|
24
|
+
|
|
25
|
+
1. **Vídeo sem trilha.** A trilha entra depois do corte seco (`references/som-e-trilha.md`). Se o vídeo já tem música, renderize de novo sem ela. O script avisa quando o fundo está alto demais.
|
|
26
|
+
2. **Plano de sons** (`plano_sfx.json` do `helpers/plano_sfx.py`, em `references/som-e-trilha.md`), se os efeitos entraram por ele. Protege o ataque de cada efeito.
|
|
27
|
+
3. **Áudio só da voz** no mesmo tempo do vídeo, se tiver: o `cut.mp4` do corte (Fase 1) quando o vídeo final começa no zero do corte. Com ele as pausas são medidas na voz limpa, e o ataque de qualquer som que não é voz fica protegido.
|
|
28
|
+
4. **Render só com grafismo** (opcional, bom em vídeo com muita animação): o mesmo projeto renderizado sem a pessoa, com a mesma duração. No HyperFrames, esconda os vídeos da pessoa com CSS (`video{visibility:hidden!important}`) e renderize de novo. Com ele o corte cai onde os grafismos estão parados. Sem ele, o script usa a diferença entre quadros do próprio vídeo.
|
|
29
|
+
|
|
30
|
+
## Rodar
|
|
31
|
+
|
|
32
|
+
Com o `--directory` o comando roda dentro da pasta da skill: passe cada arquivo com o caminho completo, entre aspas.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# 1) só o plano, sem renderizar (confira o que vai sair)
|
|
36
|
+
uv run --directory "<SKILL>" python helpers/corte_seco.py final.mp4 --sfx plano_sfx.json --voz edit/cut.mp4 --so-plano
|
|
37
|
+
# 2) valendo
|
|
38
|
+
uv run --directory "<SKILL>" python helpers/corte_seco.py final.mp4 --pausa-max 0.15 --sfx plano_sfx.json \
|
|
39
|
+
--voz edit/cut.mp4 --sem-grafismo final_so_grafismo.mp4 --saida final_seco.mp4
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Opções:
|
|
43
|
+
|
|
44
|
+
- `--pausa-max 0.15`: silêncio que fica entre as frases. Suba pra 0.20 se ficar corrido demais.
|
|
45
|
+
- `--pausa-min 0.25`: só mexe em pausas a partir disso.
|
|
46
|
+
- `--inicio 0.08`: silêncio antes da primeira palavra.
|
|
47
|
+
- `--cortar 41.06-41.76,50.2-51.0`: trechos que saem de qualquer jeito (tempos do vídeo de entrada). Para tomada repetida escondida: a transcrição às vezes junta duas tomadas numa palavra só (palavra longa demais, duas rajadas de voz com silêncio no meio). Ache os tempos na onda, corte a primeira tomada e deixe a última.
|
|
48
|
+
- `--limiar -42`: força o nível de silêncio (o padrão é medido no vídeo: 30 dB abaixo da fala).
|
|
49
|
+
- `--crf 16`: qualidade da imagem.
|
|
50
|
+
|
|
51
|
+
O vídeo de entrada nunca é alterado. A saída padrão é `<video>_seco.mp4`.
|
|
52
|
+
|
|
53
|
+
## Ler o resultado
|
|
54
|
+
|
|
55
|
+
O script mostra cada pausa cortada (quanto saiu, quanto sobrou) e as pausas que ficaram, com o motivo. No fim ele confere tudo sozinho:
|
|
56
|
+
|
|
57
|
+
- **duração** da imagem e do som, que têm que bater com o esperado;
|
|
58
|
+
- **imagem**: cada quadro da saída comparado com o quadro certo da entrada ("1657 de 1657 quadros no lugar certo");
|
|
59
|
+
- **som**: cada trecho comparado com a entrada ("desvio máximo 0,1 ms"). Acima de 5 ms é voz escorregando: não entregue;
|
|
60
|
+
- **volume**: -14 LUFS, pico real até -1 dBTP;
|
|
61
|
+
- **pausas que sobraram** acima de 0,22 s: em geral são pausas com efeito sonoro no meio ou consoante fraca na borda.
|
|
62
|
+
|
|
63
|
+
Se aparecer "ATENÇÃO", leia o aviso e não entregue sem conferir.
|
|
64
|
+
|
|
65
|
+
O relatório `SAIDA.corte.json` tem os cortes e o **mapa de tempo** (`mapa`: início na entrada, fim na entrada, início na saída), pra converter qualquer tempo do vídeo antigo pro novo.
|
|
66
|
+
|
|
67
|
+
## Depois
|
|
68
|
+
|
|
69
|
+
- Assista aos trechos que o script marcou como pausa mantida e a 2 ou 3 emendas. Mande à pessoa só o vídeo, com uma linha: "tirei X pausas, o vídeo foi de A pra B segundos".
|
|
70
|
+
- Trilha agora: `references/som-e-trilha.md`, `helpers/mixar_trilha.py` no vídeo seco.
|
|
71
|
+
- Se alguma emenda ficou visível (pulo de imagem), um whoosh ou pop forçado em cima disfarça (`plano_sfx.py` com `"forcar": true` e `--aplicar`).
|
|
72
|
+
|
|
73
|
+
## Como falar com a pessoa
|
|
74
|
+
|
|
75
|
+
- "Vou tirar os espaços que ficaram entre as frases, deixando só um respiro curtinho. A legenda e as animações continuam no lugar."
|
|
76
|
+
- Se ela achar corrido demais: `--pausa-max 0.20`. Se achar que ainda sobrou espaço: confira no relatório as pausas mantidas e o motivo antes de apertar mais.
|
|
77
|
+
- Se a pausa que incomoda está no meio de uma animação longa, explique em uma frase e ofereça as duas saídas: deixar essa pausa ou re-cortar e renderizar de novo.
|
|
78
|
+
|
|
79
|
+
## Pegadinhas conhecidas
|
|
80
|
+
|
|
81
|
+
- **Trilha antes do corte**: a música pula em cada emenda e as pausas somem no meio dela. Sempre corte seco primeiro, trilha depois.
|
|
82
|
+
- **Consoante fraca no começo da palavra** ("S" de "Só", "F"): o limiar pega a vogal e morderia a consoante. O script anda até 0,12 s pra trás enquanto ainda tem som fraco e protege esse trecho.
|
|
83
|
+
- **Micro pausa dentro da frase** (menos de 0,25 s): não mexe. Cortar ali come consoante.
|
|
84
|
+
- **Cauda de efeito sonoro** pode ser cortada (a emenda tem micro fade de 8 ms). O **ataque** nunca.
|
|
85
|
+
- **Tomada repetida escondida**: palavra longa demais na transcrição ou uma rajada de voz com uma palavra só. Ouça antes de entregar e use `--cortar`.
|
|
86
|
+
- O áudio é cortado por amostra e a imagem por quadro, nos mesmos instantes. Por isso a voz não escorrega, mesmo com dezenas de cortes.
|
|
87
|
+
|
|
88
|
+
Como o script decide cada corte, em detalhe: `references/corte-seco-como-funciona.md`.
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# O corte
|
|
2
|
+
|
|
3
|
+
O corte é a base de tudo: se ele muda, os tempos da legenda, das animações e dos sons mudam junto. Por isso
|
|
4
|
+
ele vem primeiro e é revisto no estúdio antes de qualquer animação.
|
|
5
|
+
|
|
6
|
+
A regra de pausa é a do André, e vale para todo vídeo falado curto (anúncio, Reels, VSL):
|
|
7
|
+
- **Respiro é erro.** Nenhum silêncio de 0,25 s ou mais pode sobrar, nem entre frases nem dentro de um
|
|
8
|
+
trecho. A emenda fica com uns 0,12 s de silêncio.
|
|
9
|
+
- **A tomada certa é a inteira e mais limpa**, quase sempre a última. A que para no meio, repete palavra
|
|
10
|
+
("eu eu"), termina em "..." ou muda de ideia sai.
|
|
11
|
+
- **Não corte a pessoa no meio.** Fechar o respiro não é comer o fim da palavra: o S de "demais", o E de
|
|
12
|
+
"YouTube" e a sílaba final ficam.
|
|
13
|
+
- **Barulho na pausa sai junto** (cachorro, estalo de boca, respiração forte).
|
|
14
|
+
- **Nunca emende criando frase que ninguém disse**, nem tire uma ressalva ou condição ("só se", "não é
|
|
15
|
+
pra todo mundo"). Em conversa, não troque a ordem das falas para fabricar uma afirmação.
|
|
16
|
+
- Aula longa e tutorial podem guardar um respiro curto onde ajuda a entender. Pergunte no briefing.
|
|
17
|
+
|
|
18
|
+
## 1. Transcrever
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
uv run --directory '<SKILL>' python helpers/transcribe_batch.py '<VIDEOS>' --prompt 'Hubla, Kiwify, Cakto'
|
|
22
|
+
uv run --directory '<SKILL>' python helpers/pack_transcripts.py --edit-dir '<EDIT>'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `--prompt` leva só os nomes de marca, produto e plataforma do briefing, separados por vírgula. Sem ele o
|
|
26
|
+
Whisper escreve "Cacto" em vez de Cakto e "Kiwi-Fi" em vez de Kiwify.
|
|
27
|
+
- Na primeira vez baixa o modelo de voz (cerca de 1,6 GB): avise que leva alguns minutos. Depois fica em
|
|
28
|
+
cache (uns 3 s por minuto de áudio num Mac M; bem mais lento no Windows).
|
|
29
|
+
- Se um arquivo falhar, os outros seguem. Conte qual falhou e por quê.
|
|
30
|
+
- Dois vídeos com o mesmo nome (`video.mov` e `video.mp4`): nada é transcrito. Peça para renomear um.
|
|
31
|
+
- **Arquivo só no iCloud** (Mac com "Otimizar armazenamento"; comum em Mesa e Documentos): o `ffmpeg` fica parado
|
|
32
|
+
minutos sem erro nele. O `transcribe_batch.py` confere a pasta antes de abrir qualquer vídeo, pede o download
|
|
33
|
+
ao macOS (`brctl download`) e espera um pouco; se não chegar, para com `só no iCloud` e nada é transcrito.
|
|
34
|
+
Peça para a pessoa baixar (no Finder, botão direito > Baixar Agora) ou copiar os vídeos para fora do iCloud,
|
|
35
|
+
e rode de novo. Para conferir qualquer pasta antes:
|
|
36
|
+
`uv run --directory '<SKILL>' python helpers/icloud.py '<VIDEOS>'`.
|
|
37
|
+
- **`AVISO: só N palavra(s) para X s de voz`**: o Whisper devolveu o prompt ("E aí, olha só, sabe?") ou pulou
|
|
38
|
+
a fala. Acontece com trecho copiado de um vídeo maior que começa no meio de uma frase. Trecho copiado
|
|
39
|
+
começa numa pausa, antes da primeira palavra de uma frase: copie de novo e transcreva. Se não for isso, rode
|
|
40
|
+
`transcribe.py '<VIDEO>' --edit-dir '<EDIT>' --no-prompt --force`. Nunca escolha frases de uma transcrição
|
|
41
|
+
com esse aviso.
|
|
42
|
+
|
|
43
|
+
**Ruído de fundo.** Logo depois, meça:
|
|
44
|
+
`uv run --directory '<SKILL>' python helpers/noise_check.py '<VIDEOS>'`
|
|
45
|
+
Se sair `ruído leve` ou `ruído forte` em algum vídeo, conte em uma frase e ofereça a limpeza (Leve ou Forte).
|
|
46
|
+
Anote no `project.md`. A limpeza não muda o corte.
|
|
47
|
+
Na mesma saída vem uma linha `Voz` por vídeo (`helpers/voz_check.py`): `voz SATURADA`, `possível saturação`,
|
|
48
|
+
`eco de sala leve` ou `eco de sala forte`. É medida, não escuta: ouça os tempos citados antes de afirmar, conte
|
|
49
|
+
em uma frase e anote no `project.md`. O que fazer com cada um está em `references/revisao.md`, seção Voz.
|
|
50
|
+
Saturação não volta: se a frase saturada importa, pergunte se dá para regravar.
|
|
51
|
+
|
|
52
|
+
## 2. Ler, olhar e escolher as frases
|
|
53
|
+
|
|
54
|
+
Leia `<EDIT>/takes_packed.md` (nunca os `transcripts/*.json`).
|
|
55
|
+
|
|
56
|
+
**Olhe cada vídeo** em 3 quadros (10%, 50% e 90% da duração):
|
|
57
|
+
`uv run --directory '<SKILL>' python helpers/contact_sheet.py '<VIDEOS>/IMG_5262.mov' --times 3.4 17 31 -o '<EDIT>/verify/fonte_IMG_5262.png'`
|
|
58
|
+
Procure legenda ou título já gravado na imagem (pergunte se quer a legenda da skill mesmo assim) e dado
|
|
59
|
+
pessoal na tela que precise de borrão (e-mail, CPF, telefone, cartão, conversa de outra pessoa). Anote.
|
|
60
|
+
|
|
61
|
+
**Roteiro.** Se a pessoa mandou o roteiro, ele serve para conferir palavras e a ordem, nunca para tirar
|
|
62
|
+
tempo. Improviso sem erro fica. Roteiro (ou um índice de arquivos) e fala discordam ("no editor" no roteiro,
|
|
63
|
+
"num editor" na gravação): **a fala gravada vence**. O `quote`, a legenda e o texto na tela escrevem o que
|
|
64
|
+
foi dito; na dúvida entre o Whisper e o ouvido, ouça o trecho e anote em `palavras-duvidosas.md`.
|
|
65
|
+
|
|
66
|
+
**Tomadas repetidas.** Transcrever o arquivo inteiro junta tomadas ("Foi assim que nós... Foi assim que
|
|
67
|
+
nosso"). Na dúvida, veja em pedaços menores:
|
|
68
|
+
`uv run --directory '<SKILL>' python helpers/pack_transcripts.py --edit-dir '<EDIT>' --silence 0.2 -o '<EDIT>/takes_fino.md'`
|
|
69
|
+
Palavra longa demais (uma palavra de 1,5 s) ou uma rajada de voz com uma palavra só é tomada repetida
|
|
70
|
+
escondida: ouça antes de decidir.
|
|
71
|
+
|
|
72
|
+
**A ordem** segue a história, não a gravação:
|
|
73
|
+
- Anúncio direto: GANCHO (0 a 3 s) → PROBLEMA → VIRADA → PROVA → CHAMADA.
|
|
74
|
+
- Tutorial: GANCHO → PASSO 1 → PASSO 2 → PASSO 3 → RESULTADO → CHAMADA.
|
|
75
|
+
- Depoimento ou UGC: GANCHO → CONTEXTO → EXPERIÊNCIA → RECOMENDAÇÃO → CHAMADA.
|
|
76
|
+
- Gancho e corpo gravados em arquivos diferentes (lote de ganchos): um gancho + o corpo inteiro.
|
|
77
|
+
Anúncio vertical rende bem entre 20 e 45 s. Sobrou material bom? Proponha versão curta e longa.
|
|
78
|
+
|
|
79
|
+
**Conte a estratégia** em 3 a 6 linhas: as partes em ordem, com a frase de cada uma entre aspas, o que sai e
|
|
80
|
+
por quê, e a duração estimada. Espere o sim só se a pessoa pediu para aprovar antes ou se você vai tirar algo
|
|
81
|
+
que muda o sentido. Senão, siga e mostre no estúdio.
|
|
82
|
+
|
|
83
|
+
## 3. O edl_manual.json: uma frase por trecho
|
|
84
|
+
|
|
85
|
+
Escreva `<EDIT>/edl_manual.json`, com um trecho por frase (ou por pedaço de frase quando a tomada tem erro
|
|
86
|
+
no meio), já na ordem final:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"version": 1,
|
|
91
|
+
"sources": {"H01": "/caminho/absoluto/H01.MP4", "B02": "/caminho/absoluto/B02.MP4"},
|
|
92
|
+
"output": {"format": "vertical", "width": 1080, "height": 1920},
|
|
93
|
+
"grade": "",
|
|
94
|
+
"jcut": {"lead_frames": 4, "tail_trim_frames": 2},
|
|
95
|
+
"ranges": [
|
|
96
|
+
{"id": "m01", "source": "H01", "start": 3.7, "end": 6.0, "beat": "GANCHO",
|
|
97
|
+
"quote": "Esse é o fim dos editores de vídeo.", "reason": "última tomada inteira", "gain_db": 0},
|
|
98
|
+
{"id": "m02", "source": "B02", "start": 1.1, "end": 3.75, "beat": "PROBLEMA",
|
|
99
|
+
"quote": "Sabe a pior parte de ter editor?", "reason": "última tomada", "gain_db": 0}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- A chave de `sources` é o nome do arquivo sem extensão. Caminho absoluto.
|
|
105
|
+
- `start` um pouco antes da primeira palavra e `end` um pouco depois da última (0,1 a 0,3 s de folga em
|
|
106
|
+
silêncio). Nunca deixe a folga entrar na tomada de antes ou de depois: o corte pela onda aperta o resto.
|
|
107
|
+
- Retomada colada ("…profissional… Que") : comece e termine no vale da onda, nunca pegue o pedaço da
|
|
108
|
+
tomada anterior grudado no começo da nova. Na dúvida, veja no `timeline_view.py`:
|
|
109
|
+
`uv run --directory '<SKILL>' python helpers/timeline_view.py '<VIDEOS>/IMG_5262.mov' 7.5 13`
|
|
110
|
+
- `"dry": false` num trecho que não pode ser partido nos respiros: vídeo tocando na tela, som saindo da
|
|
111
|
+
caixinha do celular, música que faz parte da cena. As bordas dele ficam exatamente como você escreveu: o
|
|
112
|
+
corte pela onda não mexe e o render não faz J-cut nele. O silêncio de dentro dele aparece na conferência como
|
|
113
|
+
`fica:` e não conta como respiro.
|
|
114
|
+
- Tempo de leitura no fim (a última palavra é a conclusão e o texto precisa ficar na tela): use o
|
|
115
|
+
`segura_fim` do `projeto.json` (`modelo-projeto/LEIA.md`), não um trecho `dry: false` sem fala.
|
|
116
|
+
- `beat` e `quote` aparecem nos relatórios: capriche. `gain_db` acerta o volume do trecho (passo 5).
|
|
117
|
+
- Vídeo deitado num corte em pé (ou o contrário): o render enquadra pelo rosto. Se errar, ponha `"focus_x"`
|
|
118
|
+
(0 = esquerda, 1 = direita) ou `"focus_y"` no trecho.
|
|
119
|
+
- `grade` fica "" por padrão. Cor lavada ou escura: compare antes (`helpers/grade.py --candidates`).
|
|
120
|
+
- Conversa gravada com duas câmeras, ou com lapela: `"imagem_de": "CAM2"` no trecho mantém a voz da `source` e
|
|
121
|
+
tira a imagem da CAM2 no mesmo instante. Veja "Várias câmeras", no fim.
|
|
122
|
+
|
|
123
|
+
## 4. Corte pela onda
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
uv run --directory '<SKILL>' python helpers/corte_por_onda.py '<EDIT>/edl_manual.json' -o '<EDIT>/edl.json'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Ele mede cada fonte na onda (volume em janelas de 10 ms, guardado em `regions/onda_<nome>.npy`) e, em cada
|
|
130
|
+
trecho: começa 0,06 s antes do primeiro som de verdade (estalo de boca antes da frase não conta), recua se
|
|
131
|
+
tiver consoante fraca no começo, parte o trecho em todo respiro de 0,22 s ou mais deixando 0,06 s de cada
|
|
132
|
+
lado, apara o silêncio do fim (qualquer tamanho) para 0,06 s, estica o fim enquanto uma consoante fraca
|
|
133
|
+
ainda soa e joga fora sobra de respiração ou estalo. O fim de um trecho nunca passa do começo do próximo trecho
|
|
134
|
+
da mesma fonte (senão o mesmo som toca duas vezes). O limiar de pausa sai do chão de ruído de cada fonte; a
|
|
135
|
+
primeira linha da saída mostra quanto ficou. Trecho `dry: false` sai como `inteiro: ... bordas como escritas`.
|
|
136
|
+
|
|
137
|
+
Leia a saída:
|
|
138
|
+
- `aviso: ... está em cima de fala; pode cortar palavra`: a borda que você escreveu no `edl_manual.json` cai
|
|
139
|
+
no meio de uma palavra. Mova para a pausa mais perto (termine a palavra ou tire a palavra inteira) e rode
|
|
140
|
+
de novo.
|
|
141
|
+
- Sobrou respiro (a conferência do passo 6 mostra): rode com `--limiar` uns 3 dB mais alto que o da saída
|
|
142
|
+
(ex.: de -38 para `--limiar -35`) ou parta o trecho ali no `edl_manual.json`. Se ainda sobrar, vá até o limiar
|
|
143
|
+
que o `respiros.py` mede (em geral -29): ele é o juiz do portão, então um corte que fecha mais baixo que ele
|
|
144
|
+
deixa respiro que o portão reprova.
|
|
145
|
+
- Mic baixo (gravação do OBS, lapela longe) pode comer fim de palavra fraca. Se a conferência mostrar palavra
|
|
146
|
+
mordida, rode com `--limiar` uns 4 dB mais baixo que o da saída (ex.: `--limiar -44`).
|
|
147
|
+
- Nunca edite o `edl.json` à mão: ele é refeito a cada rodada. Mudanças vão no `edl_manual.json`.
|
|
148
|
+
|
|
149
|
+
## 5. Volume da voz
|
|
150
|
+
|
|
151
|
+
`uv run --directory '<SKILL>' python helpers/voice_levels.py --edl '<EDIT>/edl.json'`
|
|
152
|
+
Trecho 5 dB ou mais fora da referência vem com `gain_db final X`: ponha o X no trecho do `edl_manual.json`
|
|
153
|
+
e rode o passo 4 de novo.
|
|
154
|
+
|
|
155
|
+
## 6. Renderizar e conferir
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
uv run --directory '<SKILL>' python helpers/render_cut.py '<EDIT>/edl.json'
|
|
159
|
+
uv run --directory '<SKILL>' python helpers/conferir_corte.py '<EDIT>' --prompt 'Hubla, Kiwify, Cakto'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
O render do corte leva uns 30 s por minuto. O `conferir_corte.py` transcreve o `cut.mp4` e roda ao mesmo
|
|
163
|
+
tempo a medida dos respiros (`respiros.py`), o `verify_cut.py` e a folha das junções. No fim ele imprime a
|
|
164
|
+
**fala do corte, trecho a trecho**: o `quote` que você escreveu e, embaixo, o que o corte diz, em frases curtas
|
|
165
|
+
com o tempo de começo no corte. Trecho com palavras diferentes do quote vem marcado `≠ confira: falta "..."`,
|
|
166
|
+
`a mais "..."`. A mesma fala fica em `<EDIT>/fala_do_corte.md` (ou
|
|
167
|
+
`uv run --directory '<SKILL>' python helpers/pack_transcripts.py --edit-dir '<EDIT>' --corte`). Leia tudo:
|
|
168
|
+
- palavra estranha no fim ou no começo de um trecho ("matrão" no lugar de "material") é borda mordendo a
|
|
169
|
+
palavra: volte ao passo 3 e dê folga naquela borda;
|
|
170
|
+
- palavra repetida ou "eco" numa emenda é resto da tomada anterior: mova a borda para o vale da onda;
|
|
171
|
+
- `≠` só porque o quote foi escrito de outro jeito (número por extenso, muleta que saiu): tudo bem, siga;
|
|
172
|
+
- a transcrição do corte marca começo de palavra até 0,3 s adiantado. Tempo que dispara animação, som ou
|
|
173
|
+
corte na palavra vem da onda:
|
|
174
|
+
`uv run --directory '<SKILL>' python helpers/palavras_na_onda.py '<EDIT>' [--palavra 'éééé']`
|
|
175
|
+
mostra, para cada palavra que mudou, o tempo medido na onda (`pausa` é preciso; `vale` é aproximado, uns
|
|
176
|
+
0,03 s; `whisper` quer dizer que não havia marca na onda) e grava `<EDIT>/palavras_onda.json`. No
|
|
177
|
+
`projeto.json`, ponha esse tempo em segundos (`"em": 3.42`) no lugar do nome da palavra (`"em": "éééé"`,
|
|
178
|
+
que usa o tempo do Whisper). Refaça a cada corte novo.
|
|
179
|
+
- Cada render do corte muda um pouco a transcrição ("o tudo" vira "o" e "tudo", "ééé" vira "éééé"). Cena
|
|
180
|
+
própria que monta uma linha por palavra tem que aguentar uma palavra a mais ou a menos.
|
|
181
|
+
|
|
182
|
+
Avisos do verify que pedem ação: `EDGE-IN-SPEECH` e `EDGE-IN-WORD` (palavra cortada até provar o contrário),
|
|
183
|
+
`CLICK` (mova a borda 0,02 a 0,05 s para dentro da pausa), `REPEAT` (dois trechos repetem a fala),
|
|
184
|
+
`LOW-LEVEL`/`HIGH-LEVEL` (use o `gain_db` sugerido), `BLACK`, `SILENT`, `SOURCE-MISSING`. O `DEAD-AIR` não
|
|
185
|
+
deveria aparecer depois do corte pela onda; se aparecer, o trecho tinha `"dry": false` ou o limiar ficou
|
|
186
|
+
baixo demais. Refaça até sair limpo, no máximo 3 voltas; o que ficar, explique para a pessoa. O
|
|
187
|
+
`verify_cut.py --aprovar` é do preview antigo: aqui não se usa. A aprovação do corte é a pessoa dizer no chat
|
|
188
|
+
(passo 7).
|
|
189
|
+
|
|
190
|
+
**Respiros:** a parte `Respiros que sobraram` lista todo silêncio de 0,25 s ou mais no corte, com o tempo. É a
|
|
191
|
+
primeira coisa que a pessoa nota. Tem que sair vazia; o que está dentro de um trecho `dry: false` sai em
|
|
192
|
+
linha própria, `fica: ...`, e não conta. Para medir qualquer vídeo pronto:
|
|
193
|
+
`uv run --directory '<SKILL>' python helpers/respiros.py '<VIDEO>'`.
|
|
194
|
+
|
|
195
|
+
## 7. Mostrar no estúdio e aprovar
|
|
196
|
+
|
|
197
|
+
Meça onde está o rosto em cada trecho do corte (o projeto enquadra por isso; sem ele, enquadra pelo meio do
|
|
198
|
+
quadro):
|
|
199
|
+
`uv run --directory '<SKILL>' python helpers/face_layout.py --edit-dir '<EDIT>'`
|
|
200
|
+
|
|
201
|
+
Crie o projeto do vídeo, se ainda não existe (copia o modelo e anota a skill e o corte), e abra o corte no
|
|
202
|
+
estúdio, só com o vídeo e a legenda simples:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
python3 '<SKILL>/modelo-projeto/build.py' novo '<PROJ>' --edit '<EDIT>'
|
|
206
|
+
cd '<PROJ>' && python3 build.py corte && python3 build.py estudio --sem-abrir
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Como abrir o estúdio em cada app: `references/estudio.md`. Mensagem curta: duração, as partes em ordem, o que
|
|
210
|
+
saiu e o que você quer que ela olhe ("confere se não sobrou respiro e se nenhuma palavra ficou mordida").
|
|
211
|
+
- **Ajuste por tempo** ("tira de 00:12,3 a 00:12,8", "a palavra 'então' em 00:20"): o tempo é do corte. Ache
|
|
212
|
+
em `cut_timeline.json` o segmento com `out_start <= t < out_end`; na fonte, o tempo é
|
|
213
|
+
`src_start + (t - out_start)`. Mude o `edl_manual.json` (partir um trecho em dois para tirar uma palavra
|
|
214
|
+
do meio, trocar de tomada, encurtar) e refaça os passos 4 a 7. O estúdio recarrega sozinho quando o
|
|
215
|
+
`build.py corte` roda de novo.
|
|
216
|
+
- **"Ainda tem respiro"**: meça com `respiros.py` e rode o passo 4 com `--limiar` uns 3 dB mais alto e, se ainda sobrar, no limiar que o `respiros.py` mostra (em geral -29).
|
|
217
|
+
- **Aprovação** é ela dizer no chat que aprovou ("aprovado", "pode seguir"). Anote no `project.md` com a
|
|
218
|
+
data e a nota dela. Se ela já tinha autorizado fazer tudo sem parar, este é um teste interno: siga para a
|
|
219
|
+
amostra e mostre o corte junto.
|
|
220
|
+
|
|
221
|
+
Depois do corte aprovado, qualquer mudança de fala muda os tempos: refaça `transcribe.py` do `cut.mp4`
|
|
222
|
+
(o `conferir_corte.py` já faz), o `palavras_na_onda.py` se algum tempo veio dele, e o `build.py` do projeto, e
|
|
223
|
+
confira se as animações continuam na palavra.
|
|
224
|
+
|
|
225
|
+
## Várias câmeras (conversa, entrevista, lapela)
|
|
226
|
+
|
|
227
|
+
Duas ou mais câmeras (ou uma câmera e o gravador da lapela) gravaram a mesma conversa ao mesmo tempo. Cada trecho
|
|
228
|
+
tem uma voz só (`source`) e a imagem pode vir de outra câmera no mesmo instante (`imagem_de`).
|
|
229
|
+
|
|
230
|
+
**1. Sincronizar.** Com as câmeras (e a lapela) em `sources` do `edl_manual.json`:
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
uv run --directory '<SKILL>' python helpers/sincronizar_cameras.py --edl '<EDIT>/edl_manual.json' --principal CAM1 --prova
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Sem EDL ainda: `sincronizar_cameras.py '<VIDEOS>/CAM1.MP4' '<VIDEOS>/CAM2.MP4' -o '<EDIT>/sincronia.json' --prova`
|
|
237
|
+
(`LAPELA='<VIDEOS>/lapela.wav'` dá o nome da fonte; sem nome, vale o nome do arquivo sem extensão, como em
|
|
238
|
+
`sources`). A principal é a de melhor som, a lapela se houver. Sai `<EDIT>/sincronia.json`, com o `deslocamento`
|
|
239
|
+
de cada fonte em segundos (positivo: ela começou a gravar antes) e a confiança. Leia a saída:
|
|
240
|
+
- `confiança boa`: siga. `confiança media`: confira a prova com cuidado. `confiança fraca` (sai com código 1): não
|
|
241
|
+
use. Ou não é a mesma conversa, ou o som de uma é quase só ruído (câmera longe, vento). Ache uma palma no vídeo
|
|
242
|
+
e escreva o `deslocamento` à mão no JSON.
|
|
243
|
+
- `deriva de relógio`: as câmeras contam o tempo um pouco diferente (numa conversa longa, dezenas de ms no fim).
|
|
244
|
+
O render corrige pela `escala`; confira a prova no começo e no fim (`--em <segundo da principal>`).
|
|
245
|
+
- `não é uma reta`: a câmera parou, perdeu quadros ou o arquivo foi dividido. Sincronize cada pedaço como uma
|
|
246
|
+
fonte à parte.
|
|
247
|
+
- `outro deslocamento quase tão bom`: música ou som repetitivo por baixo. Confira no olho.
|
|
248
|
+
- Fonte sem áudio: pela onda não dá. Sincronize no olho e escreva o deslocamento.
|
|
249
|
+
|
|
250
|
+
**2. Conferir no olho.** Abra `<EDIT>/verify/sincronia_CAM2.png`: 5 quadros seguidos de cada câmera no instante da
|
|
251
|
+
batida mais forte, a principal em cima. Numa palma, batida na mesa ou claquete, a mão fecha no mesmo quadro nas
|
|
252
|
+
duas linhas. O `sincronia_CAM2.mp4` põe as duas lado a lado com o som da principal (boca e som juntos). Sem batida
|
|
253
|
+
no vídeo, use `--em` num "p" ou "b" bem marcado. Se a linha de baixo fecha um quadro depois, ponha
|
|
254
|
+
`"ajuste_s": 0.033` nessa fonte do `sincronia.json` (um quadro a 30 fps; um quadro antes, `-0.033`). O ajuste fica
|
|
255
|
+
guardado quando a sincronia é refeita. A lapela não tem imagem: confira de ouvido, no corte.
|
|
256
|
+
|
|
257
|
+
**3. Escrever os trechos.** `source` é de onde vem a voz; `imagem_de` é a câmera que aparece:
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
"sources": {"CAM1": "/v/CAM1.MP4", "CAM2": "/v/CAM2.MP4", "LAPELA": "/v/lapela.wav"},
|
|
261
|
+
"ranges": [
|
|
262
|
+
{"id": "m01", "source": "LAPELA", "start": 12.40, "end": 16.10, "imagem_de": "CAM1", "quote": "..."},
|
|
263
|
+
{"id": "m02", "source": "LAPELA", "start": 16.10, "end": 18.30, "imagem_de": "CAM2", "quote": "..."},
|
|
264
|
+
{"id": "m03", "source": "LAPELA", "start": 19.00, "end": 23.50, "imagem_de": "CAM1", "quote": "..."}
|
|
265
|
+
]
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
- **Troque de câmera só numa fala ou numa reação de verdade:** quando a outra pessoa começa a falar, quando ela
|
|
269
|
+
reage (ri, se surpreende, discorda) ou quando só a outra câmera mostra o que está sendo dito. Nunca a cada
|
|
270
|
+
palavra, nem a cada frase só para dar ritmo. Cada câmera fica na tela pelo menos uns 2 s, fora a reação curta.
|
|
271
|
+
- **Trocar no meio de uma fala** (m01 para m02 acima): dois trechos colados (o `end` de um igual ao `start` do
|
|
272
|
+
outro), mesma `source`, mesmo `gain_db`; só o `imagem_de` muda. O corte pela onda mede os dois como um trecho só
|
|
273
|
+
e parte na troca (sai `troca de câmera: ... a voz segue`); o render toca a voz direto, sem J-cut e sem fade ali,
|
|
274
|
+
e troca a imagem no quadro do tempo escrito (sai `voz continua do anterior`). Com `gain_db` diferente, a voz
|
|
275
|
+
leva um corte de 30 ms na troca (aviso). Troca escrita numa pausa de 0,22 s ou mais vira junção normal: a pausa
|
|
276
|
+
sai, como em qualquer corte. Pedaço de menos de 0,3 s de uma câmera vai para a vizinha.
|
|
277
|
+
- Uma voz por vez. Com duas lapelas, `source` é a lapela de quem fala; quando os dois falam juntos, use o som da
|
|
278
|
+
câmera que pega os dois.
|
|
279
|
+
- Lapela sem vídeo só entra com `imagem_de` em todos os trechos dela.
|
|
280
|
+
- `focus_x`/`focus_y` valem para a imagem que o trecho mostra. O recorte da pessoa (tela verde) sai da câmera
|
|
281
|
+
certa de cada trecho.
|
|
282
|
+
- Sincronia com outro nome: `"sincronia": "sincronia_tarde.json"` no topo do EDL (padrão: `<EDIT>/sincronia.json`).
|
|
283
|
+
|
|
284
|
+
**4. Conferir.** Passos 4 a 7 como sempre, e mais:
|
|
285
|
+
- `a CAM2 não tem imagem de ... a ... s`: ela começou depois ou parou antes. Use outra câmera nesse trecho.
|
|
286
|
+
- `mediu CAM2 em outro arquivo`: o vídeo foi trocado ou reexportado. Rode a sincronia de novo.
|
|
287
|
+
- Na folha das junções (`verify/contact_cut.png`) a troca aparece de um quadro para o outro; na fala do corte, a
|
|
288
|
+
frase segue inteira através da troca (nada repetido, nada faltando).
|
|
289
|
+
- Olhe a boca logo depois de cada troca: atrasada ou adiantada é sincronia fora. Corrija o `ajuste_s` daquela
|
|
290
|
+
câmera e renderize de novo.
|