Sticky Director — Manual do Diretor de Filmes com IA
Este repositório é um motor local de animação e filme mudo. Um personagem de silhueta preta em um moletom cinza (rigged) atua na frente de fotos (por exemplo, imagens do Google Flow), com música, som ambiente, movimentos de câmera e legendas. Você o dirige através das ferramentas MCP (.mcp.json registra sticky-studio → node mcp-server.js) ou pela CLI (node cli.js …). Ambos iniciam server.js automaticamente, e as ações de canvas abrem o estúdio (Chromium headless quando não há display).
Sempre use caminhos absolutos dos arquivos. Cada ID abaixo é validado. Valores desconhecidos retornam como
warningse não são aplicados, portanto leia os avisos.
Executando de forma autônoma: se as ferramentas MCP do
sticky-studionão estiverem disponíveis, use a CLI a partir da raiz do repositório. Cada ferramenta MCP tem uma equivalente na CLI (tabela abaixo);node cli.js snapshot <t> <abs.png>escreve um PNG que você pode abrir com visão computacional. Todos os comandos iniciam o servidor do estúdio automaticamente.
Ferramentas (MCP) ↔ CLI
| Ferramenta MCP | CLI | O que faz |
|---|---|---|
sticky_status | node cli.js status | Modo, proporção, duração, BPM / contagem de batidas, aba conectada, lista de cenas |
sticky_get_project | node cli.js get-project [out.json] | Projeto completo em formato agnóstico de agente (cenas, fxMarkers, mediaCards, audio.beats/strongBeats, backgrounds + lightProfile) |
sticky_load_audio | node cli.js load-audio <caminho> --mode silent | Carrega música/voz → {duration, bpm, beats[], strongBeats[]} |
sticky_import_photos | node cli.js import-photos <p1> <p2> … [--auto-build] | Registra fotos → [{bgId, name, path, width, height, lightProfile}] |
sticky_apply_template | node cli.js template <id> [--no-photos] | Carrega um storyboard de filme mudo ajustado ao áudio e às fotos |
sticky_set_project | node cli.js set-project <arquivo.json | '{…}'> | Envia um storyboard completo ou parcial (apenas as chaves enviadas são aplicadas) |
sticky_update_scene | node cli.js update-scene <índice|id> '{…}' | Modifica uma cena individual |
sticky_split_scene | node cli.js split <tempoSeg> [--no-snap] | Divide em um instante, ajustando à batida mais próxima (±0,35 s) |
sticky_add_fx | node cli.js add-fx <tipo> <tempoSeg> [--duration s] | Golpe de câmera / Efeito sonoro / card |
sticky_render_frame | node cli.js snapshot <tempoSeg> [saida.png] | Quadro exato como PNG (MCP também retorna como imagem) |
sticky_export_mp4 | node cli.js export | Renderização em tempo real → exports/sticky_video_*.mp4 (60 fps H.264 + AAC) |
get_status, get_project, set_project e update_scene também funcionam sem uma aba do estúdio aberta: eles leem e escrevem projects/live_state.json, e o estúdio carrega esse arquivo quando se conecta.
IDs de Referência
Emoções (10)
| id | usar para |
|---|---|
neutral | padrão, calmo |
happy | calor, alívio, pequenas vitórias |
tired | 3 da manhã, esgotamento, exaustão |
crying | luto, colapso (usar com silentMouth: quiver) |
angry | frustração |
shocked | pânico, realização |
skeptical | dúvida, olhar de soslaio |
confused | momentos de "?" |
excited | hype (olhos estrelados) |
deadpan | vazio, entorpecimento |
Gestos (18) — gesture
| id | descrição | melhor visão |
|---|---|---|
pocket | mãos no bolso do moletom (padrão relaxado) | qualquer |
idle | braços relaxados (balançam ao andar) | qualquer |
talking | mãos reagindo ao ritmo do áudio (voz) | frontal |
explain | ambas as palmas para fora | frontal |
point_screen | aponta para o lado (para um cartão de mídia) | frontal |
point_viewer | aponta para a câmera | frontal / 3/4 |
crossed | braços cruzados | frontal |
facepalm | mão sobre o rosto | frontal |
hands_head | mãos na cabeça (pânico) | frontal |
shrug | encolhe os ombros, palmas para cima | frontal |
wave | acena | frontal |
typing | senta-se em uma mesa e digita (mesa + banco desenhados) | 3/4–lateral automático |
slouch_lonely | curvatura profunda, cabeça pendurada, respiração pesada e lenta | frontal / 3/4 |
heavy_sigh | ciclo de 4,5 s: inspira → segura → desaba (ruído de respiração automático) | frontal / 3/4 |
check_phone_dark | segura um telefone brilhando; cone de luz azul no rosto e moletom | frontal / 3/4 |
sit_curb_hug_knees | senta no chão abraçando os joelhos, cabeça baixa | 3/4 automático |
look_back_horizon | fica em pé olhando para a paisagem, vento no moletom | back / 3/4 |
pull_hood_up | ação: alcança atrás e puxa o capuz para cima (~2,3 s desde o início da cena) | frontal |
Chaves de corpo e pose
| chave | valores |
|---|---|
pose | rig (articulado, padrão) · sprites v1: front, bust, side, back |
view | front, threeQuarter, side, back |
hoodUp | true / false (capuz desenhado em todas as visões; visão traseira padrão levantado) |
walkSpeed | 0 parado · 0,1–1,0 caminhando · 1,1–2,5 trote → corrida |
walkDir | left, right |
walkInPlace | true (esteira) / false (atravessa o quadro, dá a volta) |
wind | 0..1 (barra da roupa, cordões, capuz) |
silentMouth | closed (padrão) · sigh · quiver (choro / ansiedade) |
handLeft, handRight | auto, relaxed, open_palm, pointing, fist, holding_prop, in_pocket |
prop | none, phone, mug, mic, controller, book |
spineLean, headTilt, headNod | graus (≈ −25…25; headNod + = olhar para baixo) |
ikPins | { rightHand|leftHand|rightFoot|leftFoot|head: {x, y} } em unidades do rig (origem = chão entre os pés, +x = direção para onde olha, cima é negativo y; a cabeça está perto de y ≈ −300, mãos pendem perto de y ≈ −130). {} limpa |
x, y, scale, flipX | posição 0..1 (x 0,5 = centro; y ≈ 0,55 = em pé no terço inferior), tamanho (1 = padrão), espelhar |
motion | breathe (padrão para mudo), talk_bounce, walk, shake (tremor), float, none |
emotion | veja a tabela acima |
Fundos — background
Embutidos: paper_sketch, cozy_night, rainy_window, streetlight (lâmpada da meia-noite), classroom (mesa ao pôr do sol), dark_spotlight, rooftop_dusk, green_screen.
Fotos: use o bgId retornado por sticky_import_photos, ou apenas coloque o caminho absoluto da foto em background (é importada automaticamente).
Câmera e profundidade da foto
| chave | valores |
|---|---|
kenBurns | none, push_in, pull_out, drift_left, drift_right, breathing (a foto move 100%, o personagem 30% → paralaxe) |
foreground | none, bokeh, rain_streaks, window_reflection |
camera | static, zoom_in, zoom_out, pan_right, handheld (aplica-se sobre kenBurns) |
atmosphere | dust (brilha com a batida da música), rain, none |
dutchScene / spotlightScene | horizonte inclinado em toda a cena / fundo escurecido em 60% |
Correspondência de luz (harmonização da foto) — lightMatch
true = recomendado (tint 0,35, rim 0,55, exposure 0,5) · false = desligado · um número 0..1 = intensidade geral · ou { tint, rim, exposure, side } com side = auto (da foto) | left | right | back (contraluz, ambas as bordas).
Use true em toda cena com foto. Aumente rim (0,7–0,9) para pores do sol e horizontes contraluz; use side: "back" para look_back_horizon.
Transições (como uma cena ENTRA) — transitionType, transitionDur (0–2 s)
cut · dissolve (ambos os quadros são renderizados ao vivo e se misturam) · fade_black (passagem do tempo, solidão) · fade_white (flashback, realização, esperança). Cena 0 com dissolve ou fade_black faz fade-in a partir do preto. fadeOutEnd: true faz o filme escurecer no final.
Ambientes sonoros contínuos (por cena) — ambientBed, ambientVol 0..1
| id | clima |
|---|---|
none | — |
rain_window | chuva suave + trovão distante (também molha as pegadas) |
night_wind | vento solitário da meia-noite |
vinyl_crackle | poeira lo-fi aconchegante |
clock_ticking | tique reverberante a 60 BPM: 3 da manhã, insônia, vazio |
heartbeat | batimento cardíaco abafado e profundo: ansiedade, pânico |
crowd_muffle | murmúrio com filtro passa-baixa: sozinho em uma sala lotada |
Marcadores de efeitos — sticky_add_fx / fxMarkers: [{type, timeSec, …}]
- Golpes de câmera:
snap_zoom(1,0→1,25× mola no rosto),dutch_tilt,shake,spotlight(+duration,intensity0..3,dir±1 para holandês) - Efeitos sonoros / foley (10):
whoosh,pop,vine_boom,record_scratch,shutter,typing,footstep_wet,heavy_sigh_breath,phone_vibrate,door_close_echo(+volume) - Cenas também podem definir
transitionSfx(um efeito sonoro tocado no corte) efoley: true(passos automáticos a cada batida do calcanhar + suspiros; ativado por padrão no modo mudo) - Cartões de mídia:
type: "card"comcard: {kind: image|meme|post|note, text, imagePath, side: auto|left|right, hold, size}
Chaves do projeto (sticky_set_project)
| chave | valores |
|---|---|
mode | silent (apenas música, a boca nunca sincroniza lábios) · voiceover |
aspectRatio | 16:9 · 16:9-letterbox (barras de cinema 2,35:1) · 9:16 (Shorts / Reels / TikTok, 720×1280) |
fadeOutEnd | true ou segundos |
masterAmbientVol | 0..1 |
captionStyle | cinematic (serifa de filme mudo), pop, karaoke, classic, off, ou {mode, highlight, position: bottom|middle|top, chunk, uppercase, size} |
snapToBeats | padrão true: cortes ajustam à batida mais próxima |
scenes | objetos de cena planos. Tempo: coloque start/end em todas as cenas, ou nenhum e use duration / weight (distribuído sobre a música) |
fxMarkers | veja acima |
mediaCards | [{sceneIndex | timeSec, kind, text, imagePath, appear, hold, side}] |
Templates — sticky_apply_template
loneliness_3am (telefone no escuro → caminhada com capuz na chuva → abraçando os joelhos no meio-fio → horizonte ao amanhecer) · social_anxiety (curvado no canto + murmúrio da multidão → pânico com batimento cardíaco → saindo para o vento → suspiro de alívio) · burnout (digitando na mesa → olhar vazio com o relógio → fade para preto → caminhada na chuva) · discipline (acordar cansado → puxar o capuz → trote 1,2× → corrida 2,0× em direção ao nascer do sol).
Fluxo de Direção
- Observe e ouça. Veja as fotos do usuário com visão computacional (leia os arquivos de imagem) e decida o arco emocional (ex.: isolamento → ponto de ruptura → libertação → esperança). Carregue a música com
sticky_load_audio {path, mode: "silent"}e anoteduration,bpmestrongBeats(os melhores pontos de corte). - Importe e mapeie as fotos.
sticky_import_photos {paths: [...]}na ordem da história. Use cadalightProfile(tonequente/frio,brightness,lightFrom) para escolher a batida. Salas escuras e frias combinam comcheck_phone_dark/slouch_lonely+clock_ticking. Ruas chuvosas combinam com caminhadas depocketcom capuz +rain_window+rain_streaks. Por do sol e horizontes combinam comlook_back_horizon(visão traseira,lightMatch {rim: 0.8, side: "back"}) +night_wind. - Construa o storyboard com uma única chamada
sticky_set_project:mode: "silent",captionStyle: "cinematic",fadeOutEnd: true, e uma cena por foto. Dê a cada cenabackground(caminho ou bgId),gesture,emotion,view,hoodUp,kenBurns,lightMatch: true,ambientBed,transitionType(primeira cenafade_black, maioriadissolve1,0–1,5 s,fade_blackpara saltos temporais,fade_whitepara a virada em direção à esperança),subtitles poéticos e curtos (≤ 8 palavras, ou vazio), eweightpara ênfase. Adicione algunsfxMarkers(phone_vibrate,door_close_echo, umsnap_zoomno pico emocional). Verifique oswarningsno resultado. - Inspecione visualmente.
sticky_render_frameem 2–3 momentos-chave: dentro da primeira cena (após seu fade, ~1,5 s), no meio do filme, e no clímax. Verifique se o personagem está totalmente enquadrado e no chão (ajustey,scale,x), se o rim e o tint combinam com a foto (ajustelightMatch), se as legendas estão legíveis e não cobertas, e se os rostos não estão escondidos por cartões. Corrija comsticky_update_scenee re-renderize. - Exporte com
sticky_export_mp4quando o usuário estiver pronto. Leva aproximadamente a duração do filme mais a codificação. Informe omp4Path.
Guia de bom gosto para curtas mudos emocionais
- Menos enquadramentos, mais longos (4–8 s). Corte nos
strongBeats. Deixeheavy_sigheslouch_lonelyrespirar por pelo menos um ciclo completo (≥ 4,5 s). hoodUp: true= recolhimento / chuva / ansiedade; capuz abaixado = abertura, alívio.- Mantenha
walkSpeed0,4–0,6 para caminhadas melancólicas, 1,2 para um trote determinado, 2,0+ apenas para sprints climáticos. - Combine emoção e boca:
crying+quiver,tired+sigh. No modo mudo nunca usetalking. - Use um ambiente sonoro por cena em 0,4–0,8 de volume. Mude a ambientação nos cortes para marcar um novo lugar.
- Para
9:16, mantenhax≈ 0,5 escale0,9–1,1. Legendas e cartões se reposicionam automaticamente.
Exemplo de storyboard
{
"mode": "silent", "aspectRatio": "16:9-letterbox", "captionStyle": "cinematic", "fadeOutEnd": true,
"scenes": [
{ "title": "3 AM", "background": "/abs/photos/bedroom.jpg", "gesture": "check_phone_dark", "emotion": "tired",
"kenBurns": "push_in", "lightMatch": true, "ambientBed": "clock_ticking", "transitionType": "fade_black", "transitionDur": 1.2, "subtitle": "3:07 AM." },
{ "title": "Rain Walk", "background": "/abs/photos/street.jpg", "gesture": "pocket", "view": "threeQuarter", "hoodUp": true,
"walkSpeed": 0.55, "walkInPlace": false, "x": 0.25, "foreground": "rain_streaks", "ambientBed": "rain_window",
"lightMatch": true, "transitionType": "dissolve", "transitionDur": 1.2, "weight": 1.2 },
{ "title": "Dawn", "background": "/abs/photos/sunset.jpg", "gesture": "look_back_horizon", "view": "back", "wind": 0.6,
"lightMatch": { "rim": 0.8, "side": "back" }, "kenBurns": "pull_out", "ambientBed": "night_wind",
"transitionType": "fade_white", "subtitle": "Mas o sol ainda nasceu." }
],
"fxMarkers": [ { "type": "phone_vibrate", "timeSec": 0.8 } ]
}