Communitygithub.com

série-de-comédias-esboçadas-em-branco-e-preto

Produz uma série de vídeos curtos de comédia e crítica social no estilo "desenho à mão em fundo branco" (白底简笔吐槽短视频): escolha um tema, escreva o roteiro, desenhe as cenas, narre cada linha, renderize o corte, desenhe uma capa 3:4 e escreva o título, a descrição, as hashtags e o comentário fixado para o WeChat Channels (视频号). Use quando o usuário disser "按这个简笔画风格再做几期", "做一集吐槽视频并配封面", "顺便给我视频号文案" ou "这个系列再出一集". Funciona tanto para episódios únicos quanto para lotes de vários episódios. Não serve para pedidos apenas de capa ou apenas de texto, formato 9:16 vertical, filmagens reais, 3D.

O que é série-de-comédias-esboçadas-em-branco-e-preto?

Esta skill (ferramenta para agentes de IA como Claude Code, Cursor ou Codex) automatiza a produção completa de uma série de vídeos curtos de comédia e crítica social no estilo "desenho à mão em fundo branco" para a plataforma WeChat Channels. Ela executa um pipeline completo: primeiro, o agente escolhe o tema e define o tom cômico; em seguida, escreve um roteiro no formato JSON com cerca de 40 a 45 falas; depois, gera os storyboards desenhando cada cena com primitivas gráficas personalizadas (personagens, expressões, poses, balões de fala); na sequência, sintetiza a narração de cada fala usando TTS (MiniMax) e monta a trilha sonora final; renderiza o vídeo final (com e sem legendas), gera legendas SRT, cria uma capa 3:4 usando o mesmo estilo visual; e, por fim, produz os metadados de publicação para o WeChat Channels (títulos, descrição, hashtags, comentário fixado). A skill garante consistência visual entre todos os episódios da série, utilizando sempre o mesmo conjunto de primitivas gráficas e fontes, evitando qualquer deriva de estilo entre a capa e o vídeo. Ela inclui verificações rigorosas de qualidade (sobreposição de elementos, alinhamento de legendas, integridade do áudio) e oferece tratamento robusto de falhas (retentativas para TTS, fallbacks para sistemas sem ffmpeg no PATH, suporte nativo para Windows). É ideal para criadores de conteúdo que desejam produzir em lote uma série de vídeos de humor com identidade visual marcante e processo repetível.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/inhai-wiki/doodle-comedy-series/tree/HEAD

Perguntar na sua IA favorita

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

Documentação

Série de Vídeos de Comédia e Crítica Social em Fundo Branco (Desenho à Mão)

Um vídeo = um roteiro + um conjunto de storyboards + uma trilha de áudio + uma capa + um pacote de publicação. Tudo é desenhado com o mesmo conjunto de primitivas gráficas e fontes, garantindo que cada episódio da série tenha um estilo consistente e que a capa e o vídeo principal não sofram nenhuma deriva visual.

Contrato de Entrega

Cada episódio deve entregar estes 5 grupos de arquivos, sem exceção:

ProdutoArquivoEspecificação
Vídeo final com legendasout/<título>_comedia_legendado.mp41080×1440, 30fps, H.264+AAC, aproximadamente 68s
Vídeo final sem legendasout/<título>_comedia_sem_legendas.mp4Mesmo acima, removendo a camada de legendas
Arquivo de legendasout/<título>.srtLinhas com ≤ 16 caracteres, tempos crescentes e sem sobreposição
Capa 3:4out/<título>_capa.png1080×1440, usando o mesmo conjunto de linhas e fontes do vídeo principal
Material para WeChat Channelsproject_*/publish.md + publish.json3 opções de título, 1 versão de descrição, 5–8 hashtags, 1 comentário fixado

Além disso, anexe out/<título>_preview.png (tira com quatro quadros-chave) para que o usuário possa ter uma visão geral do episódio em uma única tela.

Ambiente

Python 3.10+, Pillow, NumPy, ffmpeg/ffprobe. Crie um ambiente virtual primeiro, sem modificar o Python do sistema:

python3 -m venv .venv && .venv/bin/pip install -r "$skill_dir/scripts/requirements.txt"

No macOS, o ffmpeg geralmente não está no PATH padrão; primeiro execute export PATH="/opt/homebrew/bin:$PATH". A dublagem usa mcode-tools (MiniMax TTS/ASR) e requer que a skill mcode-tools-master esteja no PATH.

Se o comando python3 apresentar o erro "You have not agreed to the Xcode license agreements" (código de saída 69), significa que o Python do sistema não está configurado corretamente. Use um interpretador alternativo para criar o ambiente, por exemplo: /opt/homebrew/bin/python3.13 -m venv .venv. Não tente modificar a licença do Xcode.

Fluxo de Trabalho

1. Definir o Tema e o Tom da Série

Episódio único: basta dar uma direção de humor. Vários episódios: defina para cada um um tom cômico exclusivo, sem repetir o mesmo tipo de piada com roupagem diferente.

  • Fluxo de autodepreciação absurda (o próprio narrador vai ficando cada vez mais absurdo)
  • Reviravolta em diálogo (duas pessoas conversando, a última frase vira o jogo)
  • Observação fria (comédia de observação, humor seco e contido)
  • Premissa absurda (levar uma premissa ridícula a sério)

Em uma mesma série, pelo menos dois tons diferentes devem estar próximos. A linguagem visual pode ser compartilhada, mas o ritmo narrativo não deve ser repetitivo.

2. Escrever o Roteiro

Leia [references/writing-style.md]. Critérios rígidos:

  • Uma frase por cena, aproximadamente 40–45 frases, 480–520 caracteres, duração total de aproximadamente 68s (número de caracteres ÷ 7,4 ≈ segundos).
  • Cada piada deve ter uma ação visível ou uma mudança de adereço para ser concretizada, não pode depender apenas da legenda.
  • O final deve inverter a relação entre os personagens e deixar uma fala que possa ser capturada como print sozinha.
  • Escreva no formato JSON: {"title": ..., "target_seconds": 68, "segments": [{"scene": ..., "text": ..., "red": [...]}]} scene é o ID da cena, red são as palavras a serem destacadas em vermelho (devem aparecer exatamente como estão em text).

3. Dividir os Storyboards

"$python_bin" "$skill_dir/scripts/build_segments.py" --story story.json --out project_ep2

As legendas são cortadas nos sinais de pontuação em linhas de ≤ 16 caracteres; o renderizador não suporta linhas com mais de 17 caracteres. O ponto de corte deve ser escolhido próximo a 10 caracteres, evitando quebrar palavras (por exemplo, "pagamentoantecipado" não pode ser cortado em "pagamentoante" e "cipado"); frases curtas entre aspas não são divididas, e não podem ser geradas linhas que comecem com 」. O script valida se as palavras em vermelho estão nas legendas, se a divisão não perdeu caracteres, se não surgiram legendas vazias com apenas pontuação, e imprime a duração estimada: caracteres ÷ 7,4 ≈ segundos. Se o desvio for superior a ±10% do alvo, um aviso será emitido — ajuste adicionando ou removendo frases, não tente compensar alterando a velocidade da fala.

4. Desenhar os Storyboards

No arquivo project_ep2/scenes.py, escreva as funções scene_<id>(c, t, d) e redefina o dicionário SCENES no final do arquivo (contendo apenas os IDs deste episódio). As primitivas de desenho estão em scripts/render/doodles.py.

  • person(c,x,y,s,expr,boss,pose,t,arms,legs): centro da cabeça em (x,y), corpo até y+307*s, expr pode ser dead/sad/happy/angry/shocked/sleep, pose pode ser stand/shrug/point/phone/pockets/walk.
  • woman(c,x,y,s,expr,t): figura materna (coque + vestido).
  • speech(c,x,y,w,h,tail,size): balão de fala; c.text((x,y),'texto',size) usa ancoragem central.
  • c.curve aceita apenas 4 pontos de controle; c.text não suporta contorno nem múltiplas linhas.

Após fazer as alterações, passe por duas verificações:

"$python_bin" "$skill_dir/scripts/check_overlap.py" project_ep2/scenes.py   # Auditoria de layout estático
"$python_bin" "$skill_dir/scripts/check_project.py" project_ep2             # Verificação da lista de contato

check_overlap.py detecta texto sobreposto a personagens, textos sobrepostos entre si e elementos fora da área de segurança. Ele já identifica duas situações que "parecem sobreposição mas não são": troca de palavras mutuamente exclusivas em if/else e blocos de fundo branco cobrindo elementos antigos. Portanto, os problemas reportados são, em sua maioria, reais — se o código de saída não for 0, corrija primeiro, não renderize diretamente.

check_project.py primeiro verifica as legendas e depois gera a lista de contato: as legendas, quando concatenadas, devem formar exatamente a mesma frase do roteiro (pontuação ajustada manualmente é permitida, mas não pode haver caracteres a mais, a menos ou palavras trocadas); legendas vazias (sem texto) também não são permitidas. Se falhar, o script sai imediatamente, sem desperdiçar tempo renderizando a lista de contato.

Para sobreposições que devem ser mantidas (por exemplo, um crachá desenhado sobre o personagem), registre-as explicitamente em scenes.py:

OVERLAP_ALLOW = {"three_years", "me_too"}

A lista de contato deve ser revisada cena por cena: a imagem corresponde à fala? O adereço está claro?

5. Dublagem

"$python_bin" "$skill_dir/scripts/build_voice.py" --project project_ep2 --speed 1.5 --gap 0.10

A síntese frase por frase é o ponto-chave deste fluxo: cada fala é sintetizada individualmente por TTS, o silêncio inicial e final é cortado e, em seguida, as falas são concatenadas com um intervalo fixo. Dessa forma, os tempos de início e fim de cada fala são conhecidos, e o asr.json é construído diretamente com base nesses tempos, garantindo que as legendas estejam perfeitamente alinhadas, sem necessidade de ASR em nível de palavra.

  • O timbre padrão é lengdan_xiongzhang (colega mais velho e frio). Se o usuário especificar outro, use o informado.
  • O TTS tem limitação de taxa de curto prazo (HTTP 429). O script usa um intervalo fixo de 10 segundos para repetir — intervalos fixos são mais eficazes do que backoff incremental.
  • Um episódio único tem aproximadamente 40–45 falas, levando cerca de 15 minutos no total, executado em segundo plano.
  • Após a síntese, faça uma verificação com scripts/tts.py asr --file project_ep2/voice.wav.
  • Para erros de reconhecimento de fonação semelhante (ex: "ban shi / ban shi shi"), altere apenas os caracteres no resultado do ASR, não mude o roteiro nem regrave.

6. Linha do Tempo, Renderização e Verificação

"$python_bin" "$skill_dir/scripts/deliver.py" project_ep2 <título> --target 68
"$python_bin" "$skill_dir/scripts/verify.py" project_ep2

deliver.py calcula o atempo inversamente proporcional à duração alvo (velocidade = áudio original / (alvo - silêncio final)), gera a linha do tempo, as legendas, a mixagem de áudio, renderiza as versões com e sem legendas, e arquiva o vídeo final e o SRT em out/.

verify.py verifica: parâmetros de codificação, decodificação do vídeo completo, temporização e comprimento das legendas, e audição do ASR. A verificação só é considerada concluída quando todos os itens estão verdes; falhas de decodificação ou problemas de temporização nas legendas devem ser corrigidos e o vídeo renderizado novamente.

7. Capa

A capa não usa imagens geradas por IA, mas sim o mesmo conjunto de primitivas gráficas e fontes do vídeo principal, garantindo zero deriva de estilo.

No arquivo project_ep2/cover.py, escreva a função illustration(c) (as primitivas de desenho já estão injetadas no namespace). No arquivo project_ep2/cover.json, escreva as linhas de texto:

{"lines": [
  {"text": "Encontro às escuras", "size": 146, "y": 170, "red": []},
  {"text": "Minha mãe arranjou sete", "size": 96, "y": 312, "red": ["sete"]},
  {"text": "Conhecer os pais e a avó", "size": 64, "y": 1196, "red": []},
  {"text": "Oitenta e sete e não enche o saco", "size": 64, "y": 1280, "red": ["enche o saco"]}
]}
"$python_bin" "$skill_dir/scripts/make_cover.py" project_ep2

As regras de layout estão em [references/cover-design.md]. A capa deve ser visualizada separadamente antes da entrega.

8. Material de Publicação para WeChat Channels

Primeiro, colete os insumos; depois, escreva o texto:

"$python_bin" "$skill_dir/scripts/make_metadata.py" project_ep2

O script imprimirá o roteiro completo, as palavras em vermelho, as palavras de alta frequência e as três últimas falas. Com base nisso, escreva:

  • 3 opções de título, com emojis de atração, cada uma com no máximo 22 caracteres (idealmente; acima disso ainda é aceitável, limite máximo de 100 caracteres).
  • 1 versão final da descrição, com 2–3 linhas, a primeira linha sendo o gancho, e as hashtags #hashtag incorporadas no texto.
  • 5–8 hashtags, que devem aparecer todas na descrição (o script validará isso).
  • 1 comentário fixado, para complementar ou fazer autodepreciação.

Depois de escrever:

"$python_bin" "$skill_dir/scripts/make_metadata.py" project_ep2 \
  --titles "Título Um" "Título Dois" "Título Três" \
  --desc "Texto da descrição #hashtag1 #hashtag2" \
  --tags "hashtag1" "hashtag2" \
  --comment "Comentário fixado"

Detalhes das regras em [references/publish-channels.md]. Os artefatos gerados são publish.md e publish.json.

Restrições Rígidas

  • Canvas 1080×1440 (3:4), 30fps, fundo branco puro, contornos de 4–6px em preto, cabeça grande e corpo fino.
  • O conteúdo principal deve estar concentrado em y=400–1050, com espaço em branco acima; a faixa de legendas começa em y=1084, tamanho mínimo da fonte 54.
  • Legendas usam a fonte Xingkai (行楷), texto branco com sombra suave escura, palavras-chave das piadas em vermelho.
  • Cada linha de legenda tem no máximo 16 caracteres; o renderizador não suporta linhas maiores.
  • Não incorpore o texto da legenda na imagem; as legendas são renderizadas em uma camada separada.
  • A capa deve usar exatamente o mesmo conjunto de fontes e linhas do vídeo principal; não é permitido mudar o estilo.
  • Mantenha os vídeos já entregues; para alterações no roteiro, use um novo diretório de projeto, não sobrescreva os episódios já entregues.

Tratamento de Falhas

  • TTS retornando 429 repetidamente: o script já faz até 40 tentativas com intervalo fixo. Se ainda assim falhar, reduza a velocidade para 1.4 e tente novamente, ou execute em lotes (--limit N para continuar, o cache ignorará as falas já sintetizadas).
  • prepare.py relatando inconsistência no ASR: significa que o asr.json não corresponde ao roteiro, geralmente porque o roteiro foi alterado sem regravar o áudio. Reexecute build_voice.py. Não use --allow-asr-mismatch para contornar o problema.
  • render.py relatando legenda muito longa: alguma legenda ultrapassou 16 caracteres. Volte ao build_segments.py e ajuste as regras de divisão.
  • check_overlap.py saindo com código diferente de 0: corrija as coordenadas uma a uma, de acordo com o ID da cena reportado, até que o código de saída seja 0.
  • Não considere a verificação de áudio concluída sem ouvir tudo; não considere a visualização completa sem assistir ao vídeo inteiro. O registro de entrega deve conter apenas as verificações realmente realizadas.

Referências

Notas para a plataforma Windows (win32)

Procedimentos equivalentes no Windows:

  • Ambiente virtual: py -3 -m venv .venv, em seguida use .venv\Scripts\python.exe no lugar de $python_bin.
  • Dependências: .venv\Scripts\pip.exe install -r "<skill_dir>\scripts\requirements.txt".
  • ffmpeg/ffprobe: instale diretamente no PATH (ex.: winget install Gyan.FFmpeg), não é necessário adicionar /opt/homebrew/bin. No entanto, os caminhos do ffmpeg em scripts/deliver.py, scripts/make_preview.py e scripts/verify.py estão codificados como caminhos absolutos do macOS; altere para ffmpeg / ffprobe para torná-los multiplataforma.
  • scripts/build_voice.py depende de mcode-tools no PATH e do curl. O Windows 10 1803+ já vem com curl integrado; se estiver ausente, use Invoke-WebRequest -OutFile <caminho> <url> como substituto.
  • Separadores de caminho: todos os scripts usam pathlib; ao passar argumentos, forneça o caminho entre aspas.

Habilidades Relacionadas