Que fait anime-reel ?
Entrée : un script + un MP3 vocal par ligne (l'utilisateur joint les deux). Sortie : un reel 9:16 et une copie 16:9, chacun avec l'audio original, plus une copie 720p de moins de 20 Mo pour WhatsApp.
Règles strictes (à chaque exécution)
- Tout dessiner en code : canvas HTML, rendu image par image dans Chrome headless, encodé avec ffmpeg. Pas de séquences libres de droits, pas de générateurs d'images. Utiliser
engine/comme base ; l'étendre, ne pas le remplacer, pour que le style reste cohérent à chaque fois. - Chronométrer chaque mot avec un alignement forcé (torchaudio MMS_FA via
scripts/align.py). Ne jamais deviner les timings. Si l'alignement échoue pour une ligne, s'arrêter et expliquer pourquoi à l'utilisateur ; ne pas se rabattre sur un espacement égal. - Afficher une planche contact d'images avant le rendu complet et attendre l'approbation.
- Demander avant d'écraser un fichier existant.
encode.shrefuse d'écraser et quitte avec le code 2 ; transmettre cela à l'utilisateur. - Conserver l'audio original intact dans le MP4 final (les lignes vocales sont seulement placées sur une timeline, jamais retraitées). Pas de musique de fond sauf demande de l'utilisateur.
Méthode
- Configuration. Exécuter
bash scripts/check_setup.sh(ffmpeg, Node, puppeteer, torch/torchaudio, uroman). Corriger tout ce qui manque avant de continuer. Exécuterbash scripts/sfx.sh <project>/sfxpour synthétiser les sons d'impact/de glissement/percussion/pop avec ffmpeg. - Diviser le script en plans. Un plan par ligne vocale. Pour chacun, écrire :
id,speaker,text(exactement ce que dit le MP3), cheminaudio,place(toit, bureau, rue, chambre, ciel, ou ajouter une nouvelle branchedrawPlace),camera(static|push|pull|pan+amount),cast,slots(gauche/centre/droit), etfx. Enregistrer sousshots.json(schéma dansscripts/build_timeline.py). Afficher la liste des plans et laisser l'utilisateur la corriger si elle est ambiguë. - Personnages. Définir chacun dans
characters(nom, peau, cheveux, coiffure pointue|carrée|longue|courte, œil, tenue, accent,color= couleur de la légende de ce personnage). Ils doivent être originaux, jamais copiés d'un anime existant. Look anime : grands yeux avec reflet, contours épais et nets, couleur unie plus exactement une teinte. Rendre la fiche personnage et conserver le JSON comme source unique de vérité afin que les personnages ne changent jamais entre les plans :node scripts/render_frames.mjs sheet timeline.json landscape out/character_sheet.png - Alignement et synchronisation labiale.
python3 scripts/build_timeline.py shots.json timeline.json workexécute MMS_FA par ligne (timings des mots) et construit la courbe d'ouverture de bouche de chaque personnage à partir de la loudness de cette ligne vocale (mouth.py). Les clignements et le mouvement d'oisiveté sont intégrés dans le moteur. Pour les lignes non anglaises,align.pyromanise avec uroman tout en conservant l'orthographe originale à l'écran. - Trucs d'anime sur les lignes clés (ajouter à
fx, temps en secondes depuis le début du plan) :speedlineslors des révélations et de la détermination,impact(images flash blanches/noires, avecsfx: "impact") sur la ligne la plus importante,shakelors des coups,chibi(+who,sfx: "pop") pour les réactions comiques. Utiliser avec parcimonie : environ un truc tous les 2-3 plans, pour qu'ils restent percutants. - Légendes et son. Les légendes de 2-3 mots sont déjà gérées par le moteur, avec le mot prononcé dans la couleur du locuteur et le reste en blanc. Les effets sonores reposent sur les mêmes repères que les impacts visuels (via
fx[].sfx). Mixer avecpython3 scripts/build_audio.py timeline.json work/audio.wav. - Planche contact, puis approbation. Choisir ~12 moments répartis sur l'épisode, incluant chaque truc :
node scripts/render_frames.mjs stills timeline.json portrait work/stills 0.5,2.0,...bash scripts/contact_sheet.sh work/stills out/contact_sheet.pngAfficherout/contact_sheet.pnget s'arrêter. Ne pas rendre la vidéo complète tant que l'utilisateur n'a pas approuvé. - Rendu après approbation, pour chaque orientation (
portrait= 1080x1920,landscape= 1920x1080, 30 images/s) :node scripts/render_frames.mjs video timeline.json portrait work/reel_silent.mp4bash scripts/encode.sh work/reel_silent.mp4 work/audio.wav out/<name>_9x16Répéter pour paysage avecout/<name>_16x9.encode.shmixe l'audio AAC 256k et écrit la copie_720p.mp4(cible ~17 Mo, toujours sous 20 Mo). Vérifier les tailles avecls -lhet les signaler.
Paramètres de rendu
- 9:16 : 1080x1920, 30 images/s, H.264 yuv420p, CRF 16, AAC 256k, faststart. 16:9 : 1920x1080, mêmes paramètres.
- Copie WhatsApp : 720p (720x1280 ou 1280x720), débit calculé à partir de la durée pour rester sous 20 Mo.
- Les légendes se situent à environ 68 % de la hauteur en 9:16 (à l'écart des 250 px supérieurs et des 420 px inférieurs de l'interface utilisateur) et à environ 86 % en 16:9.
Fichiers de cette compétence
engine/engine.js,engine/index.html: moteur canvas (personnages, lieux, lignes de vitesse, images d'impact, secousses, chibi, légendes, badge).scripts/:check_setup.sh,sfx.sh,align.py,mouth.py,build_timeline.py,build_audio.py,render_frames.mjs,contact_sheet.sh,encode.sh.