Communitygithub.com

shaharsha/generating-video-clips

Transforme une image fixe, une illustration, une case de bande dessinée ou un personnage en un court clip animé (image-vers-vidéo), choisit un modèle ou fournisseur de vidéo, synchronise les lèvres d'un personnage avec un dialogue existant, ou corrige un clip présentant des artefacts.

Qu'est-ce que generating-video-clips ?

Ce skill permet de transformer une image fixe (illustration, case de BD, personnage) en un clip vidéo court de 4 à 9 secondes à l'aide d'un modèle image-vers-vidéo, et d'y synchroniser les lèvres d'un personnage avec un fichier audio de dialogue existant. Il offre une sélection de modèles vidéo comme Gemini Omni, Veo, Seedance ou Kling, et le choix du fournisseur (Google, ElevenLabs, fal.ai). Le workflow inclut l'animation de l'image fixe via des prompts temporels précis, la normalisation et l'ajustement du clip (cadrage, offset, vitesse), puis la synchronisation labiale avec Sync 3 sur fal.ai. L'utilisateur doit évaluer visuellement chaque résultat à l'aide de feuilles d'extraction d'images (take sheets) avant validation finale, car le skill ne permet pas de visionner directement les vidéos. Il est conçu pour s'intégrer dans des pipelines d'épisodes animés ou de production vidéo plus larges.

Compatible avec~Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/shaharsha/claude-skills/tree/HEAD/skills/generating-video-clips

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Génération de clips vidéo (image fixe vers clip, puis synchronisation labiale)

Aperçu

Une image finie devient un clip de 4 à 9 s avec un modèle image-vers-vidéo. Ensuite, si un personnage parle à l'écran, un modèle de synchronisation labiale recalibre les mouvements de sa bouche sur votre propre dialogue. Vous ne pouvez pas regarder le résultat : jugez chaque clip à partir des images extraites (scripts/take_sheet.py et le skill viewing-videos), et laissez l'humain avoir le dernier mot sur le mouvement.

Prérequis : Python 3 (stdlib uniquement) et ffmpeg/ffprobe. Les clés vont dans les variables d'environnement : GEMINI_API_KEY (une clé Google AI Studio ; une clé limitée aux images fonctionne, et GEMINI_IMAGE_API_KEY est lue comme solution de repli) pour Omni, et FAL_KEY (la clé complète exactement comme fal la présente) pour la synchronisation labiale. Ne les imprimez jamais.

Choisir le modèle

ModèleAccès viaÀ utiliser pourNotes
Gemini Omni Flash 1.1 (gemini-omni-1.1-flash)Google Interactions API, clé AI StudioPar défaut pour les illustrations, les dessins animés et les cases ; a également fonctionné sur une image photoréaliste (un test)Conserve le style artistique et les visages ; n'importe quel ratio d'image (une image 2:3 est revenue en 9:16 net, donc pas besoin de recadrer ou d'étendre au préalable) ; 720p 9:16 ou 16:9 ; synchrone, ~25-35 s par clip ; ajoute son propre son (à désactiver)
Veo 3.1 / Veo 3.1 FastAPI Gemini, image comme première imageImages photoréalistesNon utilisé dans nos tests ; vérifiez d'abord la documentation actuelle
Seedance 2.5ElevenLabs Flows, ou directement ByteDanceAspect alternatifNécessitait une approbation de compte lors de l'essai
Tout modèle dans ElevenLabs FlowsAPI ElevenLabsUne seule clé pour toutL'accès API nécessite le plan Pro (402 paid_plan_required) et l'autorisation image_video_generation de la clé (401 sans elle) ; Omni y est uniquement en mode application

Pour la synchronisation labiale, Sync 3 sur fal (fal-ai/sync-lipsync/v3) est le modèle par défaut. Il fonctionne vidéo-vers-vidéo, donc il conserve le mouvement du clip et ne recalibre que la bouche. Comparaison et prix : references/providers.md.

Animer une image fixe

python3 <ce-dossier-skill>/scripts/omni_generate.py jobs.json clips/ [--takes 3] [--only S05]
{"base": "Anime cette image fixe telle quelle : même style artistique, palette, lumière et composition, et chaque personnage conserve le visage, les cheveux, la corpulence et les vêtements qu'il a sur l'image. Mouvement naturel et fluide. Rien d'écrit à l'écran, pas de bulles de dialogue, personne de nouveau, un plan continu. ",
 "jobs": {"S05": {"image": "panels/p05.png",
                  "prompt": "[0-3s] La femme en veste rouge lève le téléphone et parle, excitée. [3-6s] L'ami en sweat à capuche vert se penche en arrière sur le canapé et rit. Léger zoom avant de la caméra."}}}

Comment rédiger le prompt (guide complet avec exemples dans references/gemini-omni.md) :

  • Une chronologie par seconde, un mouvement par crochet. Le clip dure approximativement la durée de la chronologie.
  • Désignez les personnes par ce qu'elles portent, jamais par leur nom : le modèle ne sait pas qui est « Dana ».
  • Dites « parle » pour toute personne qui sera synchronisée labialement, afin que la bouche bouge déjà.
  • Fixez ce qui ne doit pas changer : « la caméra reste immobile », « une seule fenêtre sur le mur gauche », « exactement UN personnage encapuchonné », « ses mains restent à plat sur la table ». Chaque indication dans references/failure-modes.md provient d'un échec réel.

Examiner chaque prise avant de l'utiliser

python3 <ce-dossier-skill>/scripts/take_sheet.py sheet review/S09.jpg clips/S09_t1.mp4 clips/S09_t2.mp4 clips/S09_t3.mp4 --times 0.3,1,2,3,4,5,6

Lisez la feuille : les lignes sont les prises, les colonnes sont les temps. Recherchez les accessoires qui doublent, les portes ou les personnes qui apparaissent, les mains qui traversent les corps, les visages qui dérivent, et un geste effectué deux fois. Nommez la seconde exacte de chaque problème, car la correction dépend de son emplacement.

Un cut franc est facile à manquer entre les images échantillonnées. Listez-les directement ; aucune sortie signifie un plan continu :

ffmpeg -i clips/S09_t1.mp4 -vf "select='gt(scene,0.3)',showinfo" -an -f null - 2>&1 | grep pts_time

Ajuster un clip à son plan

Un montage a besoin d'un clip qui remplit exactement son plan, à la fréquence d'images du montage :

ProblèmeSolution
Mauvais début (un geste avant sa réplique, un accessoire doublé dans la première seconde)Commencer plus tard : --off 1.5.
Trop court après recadrageRalentir avec --speed 1.22 (jusqu'à ~1.25 reste correct) ; la dernière image est maintenue.
Mauvais milieuDiviser le plan : jouer la première réplique sur un recadrage qui garde le problème hors du cadre, puis couper après.
Irréparable (une porte apparaît, une deuxième personne entre)Régénérer avec un prompt verrouillé, 2-3 prises, et choisir sur une feuille.

lipsync_parts.py normalize clip.mp4 shot.mp4 --frames N --off S --speed K effectue le décalage, la vitesse, les fps, l'échelle (couvrir et centrer-couper, jamais étirer) et le maintien de la dernière image en une seule étape, et renvoie toujours exactement N images.

Synchronisation labiale du dialogue

  1. Normalisez le clip au plan : python3 <ce-dossier-skill>/scripts/lipsync_parts.py normalize clip.mp4 shot.mp4 --frames 132 --off 1.5 --speed 1.22.
  2. Divisez aux limites des répliques de sorte que chaque partie ait un seul locuteur.
    • Écrivez shot.json : chaque réplique avec son début/fin dans le plan (en secondes) et son locuteur ; frames est égal au --frames que vous avez utilisé pour normaliser. Ajoutez "skip": true pour un locuteur vu de dos, hors écran, ou un cri de foule :
      {"id": "S05", "video": "shot.mp4", "fps": 24, "frames": 132,
       "lines": [{"id": "05-1", "audio": "lines/05-1.mp3", "start": 0.72, "end": 2.31, "speaker": "maya"},
                 {"id": "05-2", "audio": "lines/05-2.mp3", "start": 2.43, "end": 4.10, "speaker": "ido"}]}
      
    • Exécutez lipsync_parts.py split shot.json parts/. En plus des parties, il écrit parts/S05_lipsync_jobs.json : une entrée par partie non ignorée, avec les chemins absolus, out déjà nommé comme l'attend join (synced/S05_<k>.mp4), et face: null.
  3. Désignez le locuteur dans chaque partie, et écrivez-le dans ce fichier jobs sous la forme "face": "x,y@<mid>" (mid est dans chaque entrée).
    • Choisissez un pixel sur son visage sur l'image du milieu de la partie.
    • Confirmez-le : take_sheet.py point parts/S05_1.mp4 check.jpg --frame 30 --xy 410,560, puis lisez l'image.
    • Les détecteurs de visage ne sont pas fiables sur les visages dessinés, alors choisissez et confirmez à l'œil. Laissez null uniquement lorsqu'un seul visage est visible.
  4. Sync : lipsync_fal.py --jobs parts/S05_lipsync_jobs.json. Attendez-vous à ~0,13 $ par seconde et ~70-150 s par partie ; 6 s'exécutent en parallèle. Les sorties existantes sont ignorées. Pour refaire une partie après avoir corrigé son visage, exécutez cette partie seule : lipsync_fal.py parts/S05_1.mp4 parts/S05_1.wav synced/S05_1.mp4 --face 410,560@30 --force (--force avec --jobs referait toutes les parties).
  5. Assemblez : lipsync_parts.py join parts/S05_plan.json synced/ final/S05.mp4. Chaque partie est forcée à son nombre exact d'images, les parties ignorées conservent leurs images d'origine, une partie sans fichier synchronisé est signalée (--strict en fait une erreur), et le nombre total d'images est vérifié.

Détails, choix du modèle et cas d'échec : references/lipsync.md.

Coûts et durées (mesurés en 2026-10)

ÉtapeQuantitéCoûtDurée
Clip Omnipar seconde de vidéo de sortie (un clip de 6 s coûte ~0,60 $ ; prévoir ~1,5 appels par plan pour les reprises)~0,10 $~30 s par appel, 4 en parallèle
Sync 3 synchronisation labialepar seconde de sortie (une partie fait généralement 3-6 s)~0,13 $~70-150 s par partie, 6 en parallèle

Erreurs courantes

ErreurRésultatCorrection
Nommer les personnages dans le prompt vidéola mauvaise personne bougedécrire par les vêtements
Garder l'audio d'Omnivoix et musique inventées sous votre dialoguedésactiver (-an)
Utiliser une prise sans feuille d'extractionaccessoires doublés et nouvelles portes livréesextraire chaque prise
Relancer tout le clip pour une mauvaise première secondenouveaux problèmes ailleursdécalage plus ralentissement
Synchroniser labialement tout un plan à deux locuteursune bouche bouge pour les deux répliquesdiviser aux limites des répliques, un locuteur par partie
Laisser le modèle choisir le locuteurle mauvais visage parle--face X,Y@FRAME
Raccourcir la clé fal401passer la clé exactement comme fal la présente
Assembler les parties sans corriger les nombres d'imagesle plan dérive et se désynchronise du montagelipsync_parts.py join

Skills associés

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

shaharsha/deck-to-video

Use when turning a slide deck plus per-slide narration audio into an mp4 video — a self-playing/self-presenting deck video, "slides to video", "presentation to mp4", a shareable WhatsApp/Slack/Drive video of a narrated deck, or when a slide video needs a per-slide progress bar / countdown / slide counter. Also use when a slide video should highlight, glow or spotlight the element being talked about in time with the voice, or when narration and on-screen animation need syncing. Also use when...

shaharsha/image-generation

Generate logos, icons, UI mockups, hero images, product shots, and other design assets using OpenAI GPT Image 2.5 (Sunburst, Flare) or Google Gemini (Nano Banana 2, Nano Banana Pro, Nano Banana 2 Lite). Use whenever the user asks to create, design, generate, mock up, render, or illustrate a visual asset, needs a transparent PNG, or asks for image prompt engineering. Picks the right model and quality for the job, writes a model-specific prompt following the official prompting rules of each...

shaharsha/producing-animated-episodes

Use when making a narrated or voiced animated video with recurring characters - an anime, cartoon or comic episode, a short for a group chat, a story video about friends, family, a class or a team - from photos, a chat export, a story idea or a script, in any visual style, Hebrew/RTL or English. Also use when such a video has subtitles or cards too fast to read, music stopping early, the ending cut off, lines buried under music, mouths out of sync, a gesture before its line, or one face...

Skills associés