Communitygithub.com

aliflazuardi/klip

Transforme um tópico em indonésio em um vídeo TikTok finalizado (MP4 1080x1920 com narração e legendas sincronizadas com as palavras) usando o pipeline Klip neste repositório. Use quando o usuário disser /klip, "buat video tentang …", "make a TikTok about …", ou pedir para renderizar uma especificação Klip.

O que é klip?

Klip é uma skill para agentes de IA (como Claude Code, Cursor, Codex) que permite criar vídeos completos para o TikTok a partir de um prompt textual em indonésio, seguindo um pipeline definido em Python. O agente atua como roteirista, gerando uma especificação JSON estruturada ("scene spec") baseada em um esquema de contrato. O usuário primeiro revisa e aprova o script, então a skill executa comandos para validar e renderizar o vídeo, incluindo narração sintética (voz masculina "Ardi" ou feminina "Gadis"), legendas sincronizadas com as palavras, clipes de banco de imagens, animações explicativas (como ícones, gráficos, recortes) e música de fundo. A skill também gerencia batch de múltiplos tópicos, oferece templates de cena (hook, explain, list_item, myth_fact, stat, compare, cta) e suporta personalização de estilo, barras de progresso e chamadas para ação. O resultado final é um MP4, uma imagem de capa, e um texto de legenda para postagem, otimizado para o formato 1080x1920 do TikTok.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aliflazuardi/klip/tree/HEAD/.claude/skills/klip

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

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

  1. Analise a solicitação. Tópico (indonésio), voz (male = Ardi, female = Gadis; padrão female; "suara cowok" = male, "suara cewek" = female), duração alvo (padrão 45 s, máx. 60).
  2. Leia o contrato se você ainda não o fez nesta sessão: schema/spec.schema.json e o exemplo de ouro examples/menguap.json.
  3. 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.
  4. Escreva a spec em specs/<slug>.json (slug = kebab-case do tópico, apenas ASCII).
  5. 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.
  6. 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).
  7. 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 em projects/<slug>/: final.mp4, cover.png (capa projetada), post.txt (com créditos do b-roll), credits.json.
  8. 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_text com 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: requer myth e fact (cada um ≤ 8 palavras). A narração afirma o mito, depois "Faktanya, …". Defina reveal_at para essa palavra ("Faktanya,") para que o cartão de fato apareça no momento certo.
    • stat: requer stat: {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 por facts[].
    • compare: requer compare: {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. Defina cta_type para 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; para comment, 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 styles lista-os (estilos klip.yaml e pacotes de marca em brands/<name>/). Os rótulos de série de um pacote de marca vêm de seu brand.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": false na spec (ou true para forçá-la); caso contrário, deixe-a não definida.
  • Música: deixe music.mood como "calm" (ou outro nome de pasta em assets/music/); defina "mood": null para não ter música. Se a renderização disser que não há música, mencione que o usuário pode adicionar faixas a assets/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 adicione name (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} onde at é a palavra da narração em que o corte cai (a palavra que nomeia o que o novo clipe mostra) e query é 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 palavras at onde 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ão validate avisa 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; prefira beats.) max_shots: 1 mantém uma única tomada contínua (raramente necessário).
    • stage (explicador ilustrado, estilo 90secondslab): sem filmagens de stock. Um background persistente (desk, paper, kraft, board ou um caminho de imagem) sobre o qual elements são construídos, cada um aparecendo em sua palavra at e 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 Lucide name), label (text, 1–4 palavras), number (text conforme mostrado, ≤ 9 caracteres, ex.: "-11%", "Rp18rb"; tone up/down o colore), bar (2–4 bars {label, value, text}), stack (name × count, ex.: moedas empilhando), highlight (caixa amarela ao redor do elemento número target). cutout/photo/icon aceitam uma label curta. Regras: um elemento por assunto da narração, a cada ~1–2 s; palavras at em ordem de narração; no máximo 6 no palco de uma vez ("clear": true em um elemento limpa o palco primeiro); o layout é automático (pos tl…br apenas para forçar um slot). Funciona com hook, explain e list_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, ou path para a própria foto do usuário, quando um adereço precisar estar exatamente correto.
    • icon: nome do Lucide name (verifique renderer/node_modules/lucide-static/icons/<name>.svg). Bom para o CTA e para ideias abstratas sem boa filmagem.
    • local: path para 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_image atualmente 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, veja projects/<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_text 2–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/visual opcionais.
  • 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_rate nã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 validate estima.
  • Frases curtas, 1–2 por cena. O on_screen_text de 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.: calm para uma batida triste ou séria, emphatic para o payoff.
  • tts_override apenas quando o TTS pronunciar algo errado (ex.: "Follow" → "Folo"). Correções gerais vão na seção lexicon de klip.yaml (teste com uv run klip say "…").
  • Saúde / finanças / segurança: apenas informações gerais, sem conselhos individuais, fontes em facts[].
  • Termine com uma cena cta e escolha seu cta_type. Comentários e salvamentos classificam um vídeo mais alto do que seguidores, então prefira-os:
    • comment quando 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 como on_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?".
    • save para dicas, passos e listas que as pessoas vão querer depois ("Simpan biar nggak lupa").
    • share quando for útil para outra pessoa ("Kirim ke teman yang suka begadang").
    • follow para 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_item consecutivos), 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; o cover.png mostrado na grade do perfil): title (3–5 palavras, a introdução) + keyword (1–2 palavras, o payoff, desenhado grande na cor de destaque), ou lines (2–3 linhas explícitas, a última é a palavra-chave), mais subtitle (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 → o on_screen_text do 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ó.

Habilidades Relacionadas