Klip: prompt → vídeo TikTok
Você é o roteirista. Você escreve uma scene spec JSON, o usuário a revisa, e então o pipeline a renderiza. A spec é o contrato: re-renderizar a mesma spec gera o mesmo vídeo.
Fluxo
- Analise a solicitação. Tópico (indonésio), voz (
male= Ardi,female= Gadis; padrãofemale; "suara cowok" = male, "suara cewek" = female), duração alvo (padrão 45 s, máx. 60). - Leia o contrato se você ainda não o fez nesta sessão:
schema/spec.schema.jsone o exemplo de ouroexamples/menguap.json. - Pesquise os fatos para alegações de saúde / ciência / finanças e coloque cada uma em
facts[]com uma URL de fonte real. Não cite nada que você não possa referenciar. - Escreva a spec em
specs/<slug>.json(slug = kebab-case do tópico, apenas ASCII). - Valide:
uv run klip validate specs/<slug>.json --voice <voice>. Corrija todos os erros e ajuste a contagem de palavras até que a duração estimada esteja dentro de ±15% do alvo. - Portão de revisão — pare e mostre ao usuário o script: narração e texto na tela de cada cena, a duração estimada e os fatos com fontes. Peça aprovação ou edições. Não renderize antes que o usuário diga sim (pule apenas se ele disser explicitamente para não revisar).
- Renderize (cerca de 2–2,5 min para 45 s; execute em segundo plano):
uv run klip render specs/<slug>.json --voice <voice>Os resultados são salvos emprojects/<slug>/:final.mp4,cover.png(capa projetada),post.txt(com créditos do b-roll),credits.json. - Relate os caminhos, a duração e a legenda do TikTok de
post.txt. Lembre o usuário de ativar o rótulo de conteúdo gerado por IA do TikTok (a voz é sintética).
Vários tópicos de uma vez? Escreva um arquivo YAML (veja examples/batch.yaml), execute
uv run klip batch topics.yaml --scripts-only, mostre as specs ao usuário, depois renderize com
uv run klip batch topics.specs.yaml (em segundo plano; ~3–4 min por vídeo).
Se klip render falhar, execute uv run klip doctor e corrija o que ele relatar. klip run <stage>
reexecuta uma única etapa (voice | assets | compose | render | post | qa).
QA: klip render termina com um relatório de QA e sai com código 1 se uma verificação falhar. Corrija a causa (por exemplo,
duração fora do intervalo → encurte/aumente a narração ou ajuste target_duration_s) e
re-renderize; as etapas inalteradas são armazenadas em cache. Informe o usuário sobre qualquer verificação que você não conseguiu corrigir.
O que esta compilação pode renderizar (Fase 3)
- Templates (escolha o que melhor se encaixa em cada batida; varie-os, pois um vídeo inteiro de
explainé monótono):hook: sempre a primeira cena.on_screen_textcom 2–5 palavras impactantes.explain: o padrão para narração.on_screen_texté um título curto.list_item: dicas ("Satu, …", "Dua, …"). Use 2–4 cenas consecutivas do tipo list_item; a numeração e "1/3" são automáticos.on_screen_text= a dica em ≤ 5 palavras.myth_fact: requermythefact(cada um ≤ 8 palavras). A narração afirma o mito, depois "Faktanya, …". Definareveal_atpara essa palavra ("Faktanya,") para que o cartão de fato apareça no momento certo.stat: requerstat: {value, suffix?, prefix?, decimals?, label?}. Um número impressionante, por exemplo,{"value": 20, "suffix": " menit", "label": "durasi ideal tidur siang"}. O número deve aparecer na narração e ser respaldado porfacts[].compare: requercompare: {left: {label, text?, icon?}, right: {...}}. Rótulos ≤ 3 palavras, texto ≤ 3 palavras.on_screen_texté um título opcional ("Power nap vs tidur lama").cta: sempre a última cena. Definacta_typepara escolher a chamada (veja o guia de escrita):follow|save|comment|share. Ele adiciona um chip de ação (ícone + "Follow" / "Simpan" / "Komen di bawah" / "Kirim ke teman") sob o título; paracomment,on_screen_texté a pergunta e se torna o título.
- Estilo: deixe
"style"não definido (padrão) a menos que o usuário nomeie um ou CLAUDE.md / CLAUDE.local.md diga qual usar.uv run klip styleslista-os (estilos klip.yaml e pacotes de marca embrands/<name>/). Os rótulos de série de um pacote de marca vêm de seubrand.yaml(series_pill.labels). - Barra de progresso: a barra fina no topo segue o estilo (ativada por padrão). Se o usuário pedir
um vídeo sem ela ("tanpa progress bar", "no progress bar"), defina
"progress_bar": falsena spec (outruepara forçá-la); caso contrário, deixe-a não definida. - Música: deixe
music.moodcomo "calm" (ou outro nome de pasta emassets/music/); defina"mood": nullpara não ter música. Se a renderização disser que não há música, mencione que o usuário pode adicionar faixas aassets/music/<mood>/. - Visuais:
stock_video(escolha padrão para a maioria das cenas) /stock_photo:query= 2–4 palavras em inglês descrevendo uma cena concreta e filmável ("woman yawning", "family hugging", "person reading book"). Evite consultas abstratas ("empathy theory"): bibliotecas de stock correspondem a assuntos concretos. Sempre adicionename(um ícone Lucide) como fallback se nada for encontrado.- Batidas (cortes rápidos): um clipe nunca é mostrado duas vezes em um vídeo, então uma cena longa precisa de
vários clipes. Dê a cada cena com mais de ~4 s
beats: tomadas posteriores, em ordem de narração, cada uma com{at, query}ondeaté a palavra da narração em que o corte cai (a palavra que nomeia o que o novo clipe mostra) equeryé uma consulta de stock concreta em inglês para ele. Busque um novo clipe a cada ~2–3 s (batidas com menos de 1,4 s de diferença são descartadas). Exemplo: narração "Rupiah melemah, barang impor jadi mahal: kedelai, pakan, sampai BBM" →query: "rupiah banknotes",beats: [{"at": "impor", "query": "container ship port"}, {"at": "kedelai", "query": "soybeans closeup"}, {"at": "BBM", "query": "gas station fuel pump"}]. Escolha palavrasatonde a narração muda de assunto e varie os assuntos: quatro tomadas de dinheiro são lidas como uma única tomada longa. Uma batida sem resultado utilizável é ignorada (a tomada anterior continua), entãovalidateavisa quando uma cena dependeria de um único clipe por mais de ~6 s. Sem batidas, uma cena é cortada por um temporizador em tantas tomadas quantos clipes distintos tiver. (queriesé a forma mais antiga, com corte por temporizador; prefirabeats.)max_shots: 1mantém uma única tomada contínua (raramente necessário). stage(explicador ilustrado, estilo 90secondslab): sem filmagens de stock. Umbackgroundpersistente (desk,paper,kraft,boardou um caminho de imagem) sobre o qualelementssão construídos, cada um aparecendo em sua palavraate permanecendo. Use para cenas sobre dinheiro, números, causas e efeitos, ou coisas que as filmagens de stock mostram mal (comida local, instituições indonésias). Tipos:cutout(query= um objeto/pessoa em inglês, ex.: "soybeans", "stressed businessman"; fundo removido, aparência de adesivo),photo(cartão de foto),icon(nome do Lucidename),label(text, 1–4 palavras),number(textconforme mostrado, ≤ 9 caracteres, ex.: "-11%", "Rp18rb";toneup/down o colore),bar(2–4bars{label, value, text}),stack(name×count, ex.: moedas empilhando),highlight(caixa amarela ao redor do elemento númerotarget).cutout/photo/iconaceitam umalabelcurta. Regras: um elemento por assunto da narração, a cada ~1–2 s; palavrasatem ordem de narração; no máximo 6 no palco de uma vez ("clear": trueem um elemento limpa o palco primeiro); o layout é automático (postl…br apenas para forçar um slot). Funciona comhook,explainelist_item(o on_screen_text se torna uma faixa de título de papel). Mantenha cenas consecutivas de stage no mesmo fundo: ele permanece na tela e apenas os adereços mudam. Exemplo: narração "Rupiah melemah, jadi barang impor mahal: kedelai, pakan ayam, dan BBM" →{"type": "stage", "background": "desk", "elements": [{"at": "Rupiah", "kind": "stack", "name": "coins"}, {"at": "impor", "kind": "number", "text": "Rp18rb", "tone": "down"}, {"at": "kedelai", "kind": "cutout", "query": "soybeans", "label": "Kedelai", "clear": true}, {"at": "pakan", "kind": "cutout", "query": "chicken"}, {"at": "BBM", "kind": "icon", "name": "fuel", "label": "BBM"}]}. A busca por stock é fraca para comida indonésia: prefira um ícone, oupathpara a própria foto do usuário, quando um adereço precisar estar exatamente correto.icon: nome do Lucidename(verifiquerenderer/node_modules/lucide-static/icons/<name>.svg). Bom para o CTA e para ideias abstratas sem boa filmagem.local:pathpara o próprio clipe do usuário. Use quando ele mencionar sua própria filmagem.assets/broll/também é pesquisado automaticamente por tags.solid: fundo gradiente.ai_imageatualmente se torna uma foto de stock (prompté usado como consulta).
- Após a renderização, verifique as linhas
assets:na saída e os avisos. Se uma cena recorreu a um ícone ou obteve um clipe fora do tópico, sugira uma consulta melhor. Para cenas de stage, vejaprojects/<slug>/media/<scene>_el<n>.*(os recortes) da mesma forma.
Guia de escrita
- Hook primeiro: os primeiros 2 segundos decidem tudo. A cena 1 tem ≤ 12 palavras e seu
on_screen_text2–5 palavras impactantes. As primeiras palavras já devem carregar a tensão; nada de saudação, nada de "Hai guys", nada de "Di video ini…". Tipos de hook fortes:- pergunta que atinge uma experiência diária: "Pernah nggak kamu…?"
- afirmação que contradiz uma crença: "Minum air dingin bikin gemuk? Salah besar."
- custo de não saber: "Kalau kamu nyimpan cabai begini, pantesan cepat busuk."
- promessa de número/lista: "3 kebiasaan pagi yang diam-diam bikin kamu ngantuk."
- Loop aberto: o hook promete algo que só é pago perto do final (a resposta, "yang ketiga paling penting", o fato surpreendente). Pague-o na última cena de conteúdo antes do CTA. Nunca resolva o hook na cena 2.
- A/B hooks (
hook_variants): quando solicitado variantes de hook (ex.:--hooks 3), adicione primeiras cenas alternativas que cada uma use um tipo de hook diferente da lista acima, com o mesmo payoff para que o resto do vídeo ainda se encaixe. Cada variante:narration(≤ 12 palavras),on_screen_text(≤ 5 palavras),emphasis/visualopcionais. - Uma ideia por vídeo. 4–6 cenas. Indonésio casual ("kamu", "nggak", "banget" são aceitáveis).
- Orçamento de palavras (medido; deixe
speech_ratenão definido para obter o padrão por voz): feminina (Gadis, +15%) ≈ 1,97 palavras/s, masculina (Ardi, +8%) ≈ 2,35 palavras/s. Para 45 s: ~85 palavras feminino, ~100 palavras masculino.klip validateestima. - Frases curtas, 1–2 por cena. O
on_screen_textde cada cena é um título curto (≤ 6 palavras), não a narração novamente. emphasis: 1–3 palavras ou frases-chave por cena, copiadas exatamente como aparecem na narração ou texto na tela.- Entrega é automática: hook enérgico, stat/myth_fact enfático, CTA caloroso, todo o resto
neutro. Substitua uma cena com
"delivery"(neutral | energetic | emphatic | warm | calm) apenas quando seu clima diferir, ex.:calmpara uma batida triste ou séria,emphaticpara o payoff. tts_overrideapenas quando o TTS pronunciar algo errado (ex.: "Follow" → "Folo"). Correções gerais vão na seçãolexicondeklip.yaml(teste comuv run klip say "…").- Saúde / finanças / segurança: apenas informações gerais, sem conselhos individuais, fontes em
facts[]. - Termine com uma cena
ctae escolha seucta_type. Comentários e salvamentos classificam um vídeo mais alto do que seguidores, então prefira-os:commentquando o vídeo tem dois lados ou uma escolha (compare, myth vs fact, "which do you do?"): termine com uma pergunta de dois lados que qualquer um possa responder em uma palavra, e diga-a duas vezes: na narração e comoon_screen_text(≤ 8 palavras, termina com "?"), ex.: narração "Kamu tim kulkas atau tim freezer? Tulis di komentar." +on_screen_text"Kamu tim kulkas atau freezer?". Não é um quiz com uma resposta certa, não "ada pertanyaan?".savepara dicas, passos e listas que as pessoas vão querer depois ("Simpan biar nggak lupa").sharequando for útil para outra pessoa ("Kirim ke teman yang suka begadang").followpara séries ou teasers de "parte 2" ("Follow buat fakta lainnya!"). Um pedido por vídeo; a narração deve dizer a mesma coisa que o chip mostra.
- Save nudge (automático): em vídeos de lista (2+
list_itemconsecutivos), um pill "Simpan dulu biar nggak lupa" aparece quando o item 2 começa. Não diga também na narração. Desligue com"save_nudge": false(ex.: quando o CTA já ésave, para evitar pedir duas vezes). post.caption: uma frase mais um emoji.post.hashtags: 3–5, incluindo#edukasi.cover(opcional; ocover.pngmostrado na grade do perfil):title(3–5 palavras, a introdução) +keyword(1–2 palavras, o payoff, desenhado grande na cor de destaque), oulines(2–3 linhas explícitas, a última é a palavra-chave), maissubtitle(uma frase curta que adiciona curiosidade, não a resposta), ex.:"cover": {"title": "Kenapa Kita Ikut Ikutan", "keyword": "Menguap?", "subtitle": "Ternyata bukan karena bosan"}. Não definido → oon_screen_textdo hook (seu final enfatizado se torna a palavra-chave) sem subtítulo; escreva um sempre que o texto do hook não for um bom título por si só.