Fluxo de trabalho Edit-video
Siga estas etapas todas as vezes que o usuário enviar um vídeo bruto. Raiz da ferramenta: /home/user/video-workflow
(VW=/home/user/video-workflow). Use um diretório de trabalho novo por vídeo no scratchpad, ex: $SCRATCH/<nome>/work.
Leia STYLE_GUIDE.md (o estilo), EFFECTS.md (a biblioteca de 17 efeitos - use vários em CADA vídeo) e
templates/STORYBOARD_REFERENCE.md (sintaxe) antes da etapa 4.
0. Configuração (uma vez por contêiner)
$VW/vw.sh setup. Se avisar que huggingface.co está bloqueado, diga ao usuário que a transcrição não pode ser executada até que ele permita
huggingface.co (e *.hf.co) nas configurações de rede do ambiente; não invente uma transcrição.
1. Preparar + transcrever + propor cortes
$VW/vw.sh prep RAW.mp4 WORK [--language ro|en] [--model small|medium]
- A filmagem SDR "lavada" (HDR do iPhone re-codificado por um aplicativo compressor sem mapeamento de tom: pretos leitosos, brancos opacos - ex: *_compressed.mp4) é detectada (ponto preto acima de Y45, ou ponto branco abaixo de Y203 - brancos opacos ao lado de clipes .mov mapeados por tom do mesmo conjunto) e seus níveis são restaurados em prepare.py (alongamento de luminância para Y34..~215, croma x1.08), combinando com a aparência natural aprovada de HDR com mapeamento de tom (Mindri-Box-v3).
- APARÊNCIA DE COR APROVADA em cada clipe (regra do usuário - "o filtro que conversamos"): após a normalização, prepare.py
executa
look_matchemsource.mov: ele mede os 60% superiores do quadro (fundo + pessoa) e aplica uma curva de tom + saturação para que cada clipe corresponda à aparência aprovada (Mindri-Box-v3 / Comanda-Ionut-v2/v4: pretos profundos, laranja vívido, camiseta branca limpa; alvos p5 38, p25 52, p50 76, p95 226, saturação 59). Apenas escurece sombras/médios, eleva brancos opacos e adiciona cor (máx. 35 níveis por ponto, saturação máx. x1.3); clipes já dentro da aparência são deixados intocados. Vídeos com múltiplos clipes assim combinam entre si. Agradepermanecenaturalno topo. - Filmagem HDR de telefone (iPhone: HLG/PQ, BT.2020, 10-bit, Dolby Vision) é mapeada por tom para SDR BT.709 automaticamente (zscale + hable, 100 nits) - sem isso tudo parece pálido e leitoso. A saída é marcada como BT.709.
- Normaliza para 30 fps CFR, 1080x1920 (corte de cobertura), detecta o rosto (MediaPipe full-range) e mede o
brilho da zona do título →
layout.json(zonas seguras; zonas brilhantes fazem os títulos ficarem em caixas e o texto de vidro tingido). - Transcreve com timestamps de palavras (mantém "hum"/recomeços visíveis) →
transcript.json. - Auto-marca preenchimentos, gaguejos, palavras cortadas e recomeços →
edit.json+review.txt. - Use
--model mediumpara áudio em romeno ou ruidoso; detecção de idioma automática caso contrário. - Se a origem era paisagem (aviso impresso), avise ao usuário que foi cortada ao centro.
1b. Vários clipes brutos (uma história)
Quando o usuário enviar vários clipes, transcreva cada um primeiro e determine a ordem a partir do que é dito
(geralmente a ordem de filmagem). Execute as etapas 1-2 e cut por clipe (WORK_k), depois junte-os:
python3 $VW/scripts/merge_clips.py WORK WORK_1 WORK_2 … → uma linha do tempo; layout.json mantém o enquadramento de cada clipe
(clips[]), e o renderizador e efeitos usam o enquadramento do clipe que estiver na tela. Corrija o texto da legenda
no words.json mesclado, então continue na etapa 4 em WORK. Coloque uma transição (zoom_through, flash,
glitch) em cada limite de clipe.
2. Revisar a edição (etapa de julgamento - não pule)
Leia WORK/review.txt de cima a baixo como um editor e corrija WORK/edit.json:
- Remova: takes com falha / recomeços que o detector não pegou (mantenha o ÚLTIMO take bom), frases atrapalhadas, "peraí, deixa eu refazer", apartes fora do assunto, introduções mortas ("fala galera", "então, hum, hoje…") - o vídeo deve começar na linha de gancho.
- Mantenha (
"keep": [idx…]): palavras que o detector removeu erroneamente (repetição deliberada, "muito muito", listas). - Palavras de baixa confiança
(?): verifique o contexto; uma palavra ouvida errada é um problema de legenda (corrija o texto emtranscript.json, mantenha o timing), não um corte. - Parâmetros de ritmo:
max_gap0.20 s (apertado, estilo do guia); aumentepad_afterpara 0.14 se os finais das palavras soarem cortados. Então:
$VW/vw.sh cut WORK
Deve imprimir Sync check: … OK. Se MISMATCH → pare e investigue (nunca envie). Os pontos de corte são ajustados ao quadro e
colocados no silêncio, então a sincronia labial é exata. Re-leia WORK/words.json (nova linha do tempo) - todos os timings posteriores o usam.
3. Corrigir texto da legenda
Em words.json corrija erros ortográficos, nomes de marca, números ("dez" → "10" quando ficar melhor de ler), e mantenha o
idioma e diacríticos do usuário (ă â î ș ț). Não altere timings.
4. Storyboard (etapa de julgamento)
Escreva WORK/storyboard.json (sintaxe: templates/STORYBOARD_REFERENCE.md, exemplo: templates/storyboard.example.json).
Primeiro escreva um plano curto como uma tabela (tempo · o que é dito · visual · transição · SFX) e mostre ao usuário na
resposta no final. Regras do guia de estilo:
Gancho (0-3 s) - a afirmação mais forte como elementos title gigantes, um por frase, 3+ mudanças visuais em 3 s
(troca de título / troca de fonte / flash / punch-in). Misture fontes de título (serif → heavy → itálico dourado). Sem introdução.
Corpo - algo muda na tela a cada ~1-3 s:
- Ilustre o que é dito, sincronizado com a palavra exata que o menciona (início do elemento
start= início dessa palavrastart): ferramentas/apps →strike(quando rejeitado) oucard; instruções/prompts →prompt(digitando); números →counter/stat; etapas → badgesstep; enumerações →list; uma frase-chave →title; uma captura de tela/logo que o usuário forneceu →image/card. - Uma palavra-chave herói por frase em
captions.keywords(a palavra que carrega o significado, não preenchimento). - Zoom punch-in (
zooms, escala 1.06-1.12, nunca mais) em linhas de ênfase, alternando com 1.0 - isso mantém o palestrante no enquadramento normal enquanto esconde cortes de salto. - Transições estilizadas apenas em mudanças de seção / payoff, no máximo uma a cada 5-10 s:
flash,glitch,leak,whoosh,impact. - A cada 10-15 s mude o modo (ex: uma sequência de cartões de UI, depois um momento de título grande, depois uma estatística).
Palestrante sempre visível: os gráficos vão em pos: "top" (acima da cabeça, ajustado automaticamente à zona livre de
layout.json) ou "lower" (área do peito, acima das legendas). Nunca center sobre o rosto. Títulos podem sobrepor ligeiramente o topo
da cabeça (essa é a aparência), nunca os olhos/boca.
Regras de referência "Editadas" (EFFECTS.md, final) - obrigatório em cada vídeo: sempre uma grade de cor
(padrão natural - as próprias cores da filmagem, sem filtro estilizado; outras aparências apenas sob solicitação), trackamento de rosto 1-3 vezes a cada 30 s, photos da internet para coisas concretas
que são nomeadas (scripts/images.py, veja-as primeiro, créditos na resposta), títulos combo para o gancho
e cabeçalhos de seção, numcards para enumerações.
Biblioteca de efeitos (EFFECTS.md) - obrigatório em cada vídeo: cerca de um momento de efeito a cada 4-6 s do vídeo final
(30 s → 5-7, 60 s → 9-12), cada um combinado com o que está sendo dito, sem repetição dentro de ~15 s, misturando famílias de câmera, recorte e UI.
Coloque um no gancho. Exemplo com todos eles: templates/storyboard.effects-example.json.
CTA / final (se o usuário disse o que quer): card comment (CTA de palavra-chave) e/ou follow nos últimos 4-6 s.
Tema da marca (escolha permanente do usuário) - tudo na tela: storyboard "style": "depth", "palette": "mindricel"
→ títulos, cards, etapas, tiles/números, gráficos, listas de verificação, notas, cartões de órbita, texto de vidro e produtos todos usam a
aparência de referência de profundidade na paleta mindricel.ro (laranja #FF6600 gradiente, tinta #0A0A0A painéis, texto branco, contornos
finos escuros). Nomes de fontes editoriais em linhas de título são mapeados automaticamente; use laranja (#FF6600/#FF8533) ou branco para
rabiscos. Nunca misture as cores editoriais verde/creme.
Legendas (escolha permanente do usuário - referência "lockup", copiada 1:1): "captions": {"style": "lockup", "palette": "scene"} (nenhuma lista de palavras-chave necessária; os papéis são automáticos).
- Cada frase falada (2-5 palavras) é UMA composição tipográfica: palavras de conteúdo são GRANDES (Montserrat ExtraBold, ~170 px, apertado -0.045em, como falado - principalmente minúsculas), palavras funcionais são PEQUENAS (Montserrat SemiBold, 1/3 do tamanho, branco com um contorno escuro fino) aninhadas nos cantos das palavras grandes - antes de uma palavra grande: canto superior esquerdo, depois dela: canto inferior direito ("mais de $10.000 por mês"). Uma palavra grande por linha, linhas empilhadas firmemente e deslocadas para esquerda/direita.
- Preenchimentos por palavra grande: números/dinheiro → gradiente verde, palavras negativas (nu, fără, stop, greșeli, scump...) → gradiente
vermelho, outras → gradientes das cores da filmagem DAQUELE clipe (paleta
body_profile.py) ou branco; automaticamente mais profundo/saturado em cenas claras e claro em cenas escuras para que sempre se leia. - A posição alterna cabeça / peito / cabeça / acima da cabeça; enquanto títulos ou gráficos ocupam o topo, as frases permanecem no peito. Uma frase na FRENTE nunca cobre o rosto (cabelo ao queixo): ela se move para o peito ou acima da cabeça.
- PROFUNDIDADE (regra do usuário, CADA vídeo): cerca de 40% das frases (
behind_share0.4) ficam ligeiramente ATRÁS da cabeça (camada de trás + recorte). A busca cobre alturas desde "borda inferior roçando o cabelo" até o meio do rosto e desloca-se lateralmente até ±240 px. Um ponto é válido apenas se a cabeça realmente sobrepor uma palavra (behind_min_overlap5%), cada palavra grande está no máximo 25% escondida (palavras curtas ~4% por letra, ex: máx. 16% para 4 letras), e a parte superior das primeiras/últimas letras permanece visível. Usa a silhueta de pior caso ao longo do clipe (occ_max), escalada por qualquer zoom ativo naquele momento. Nunca 3 atrás consecutivas, nunca enquanto gráficos ocupam o topo. Verifique esses quadros no QA. - Legibilidade: cada palavra grande tem um contorno fino (escuro em áreas escuras, claro em áreas brilhantes) + sombra suave; palavras
pequenas têm um contorno escuro. As cores de preenchimento são escolhidas a partir do brilho EXATAMENTE abaixo da frase (mapa
lumde body_profile.py): tons claros sobre áreas escuras, tons profundos sobre áreas claras - a paleta permanece a da filmagem. - QA: verifique se nenhuma frase frontal toca o rosto e se as frases atrás são lidas claramente (quadros abertos em cada uma).
- Movimento: a frase entra lateralmente com fantasmas de motion-blur, as palavras aparecem conforme são faladas (blur-in rápido), e sai na direção oposta quando a próxima frase começa (sem espaços entre frases).
- Tempo de leitura: uma frase aparece
lead0.25 s antes de ser falada (suas palavras ligeiramente à frente da voz), frases mais curtas quemin_phrase1.0 s se fundem com a próxima/anterior (máx. 7 palavras / 34 caracteres), a última frase segurahold1.2 s. O vídeo mantémtail0.8 s de imagem após a última palavra (parâmetrosedit.json; se a filmagem terminar antes, o último quadro é segurado). Múltiplos clipes:"tail": 0em cada clipe, exceto o ÚLTIMO. - Fundos mistos (ex: camiseta branca sobre um fundo escuro, spread de brilho > 0.17 sob a frase): um tom médio vívido da própria cor do vídeo com o contorno escuro (veja "Cores da legenda" abaixo).
- Guarda de contraste: se a cor de uma palavra estiver muito próxima em brilho do que está atrás dela (
min_contrast0.42), a mesma cor recebe seu tom de máximo contraste + o contorno fino - nunca fica branca (regra do usuário). - Tópicos sensíveis / sérios (funerais, doença, perda, pedidos de desculpa...): mantenha a aparência lockup mas
"motion": "fade"(fade-in suave, sem chicotes),"semantic": false(sem cores de palavras verde/vermelho), sem glitch/pixel/vertigo/frame-break, sem SFX marcantes (nenhum é aceitável), push-ins lentos e tracking suave apenas, força da grade ~0.6, e sem tema laranja mindricel a menos que seja a própria marca do usuário. Avise ao usuário que o tom foi adaptado e ofereça a versão enérgica. - Estilos de legenda mais antigos (
cleanheadlines,depth,bold,editorial) apenas sob solicitação.
Números: tiles agora renderizam como UMA pílula arredondada escura com grandes dígitos limpos contando para cima e uma unit
opcional em laranja (ex: {"type": "tiles", "text": "400-600", "unit": "cm³"}); os quadrados antigos apenas com "look": "classic".
Transições (referência imobiliária): em mudanças de clipe / mudanças de seção use flash_blur (desfoque superexposto),
pixelate (dissolução de pixel, também bom quando um elemento/imagem sai), zoom_through, e cortes de salto com zoom (punch
alternando 1.0 / 1.1-1.15 em cortes de salto). Mantenha glitch raro.
Sons (vídeo de referência SFX do usuário, extraído - a ÚNICA biblioteca; o antigo sintetizado foi excluído a pedido):
10 WAVs em sfx/ (pico -3 dBFS): loading (tique digital 0.9 s), click, air (sibilo aéreo curto), tap (pop suave),
marker (traço de marcador de texto), tick (tique minúsculo de UI), blur_hit (impacto marcante + cauda), swish, sub_boom (queda
sub-grave), logo_hit (grande impacto de revelação). Mapeado automaticamente (compose.py): flash_blur → blur_hit,
transições zoom_through/leak/whoosh/swoosh → swish, flash → air, pixelate/glitch/rewind → loading, impact → sub_boom, punch → click;
title/stat/combo → blur_hit (primeiro combo + sub_boom), strike/doodle/wall/accent → marker, cards/app/image/product info → tap,
products → air + swish, steps/lists/checklists/numcards → click, counters/tiles/charts → loading, glass/cover → sub_boom,
card follow → logo_hit, typing → tick. Nomes antigos (pop, whoosh, deep_bass, ding, ...) ainda funcionam via SFX_ALIAS.
Densidade de SFX (usuário: "use efeitos sonoros com mais frequência") - padrão "sfx_density": "high": além dos sons de elementos e
transições, compose.py adiciona sons extras silenciosos (-15..-19 dB) em mudanças de frase de legenda (air quando a frase vai
atrás da cabeça, tap em números/preços, alternando swish / tick caso contrário; de WORK/caption_events.json), em cada
corte de salto (click), quando um gráfico superior sai (air) e em movimentos de câmera push/track. Cada som extra mantém >= 0.3 s dos
outros (~1 som por segundo). Tópicos calmos: "sfx_density": "normal" (automático quando legendas motion: "fade").
MENOS LEGENDAS (regra do usuário, CADA vídeo): legendas em cada frase são cansativas - apenas ~60% das frases recebem uma legenda
(captions.density 0.6 = 40% menos). O renderizador mantém as frases mais significativas (palavras de conteúdo, números/preços,
negativos, nomes, perguntas/exclamações; preenchimentos como bă/mă/băi/deci pontuam baixo), sempre a primeira e a última frase,
e nunca 4 frases consecutivas sem