> # ⛔ ABANDONNÉ — 2026-09-02 > > **Ce plan n'est pas réalisable en l'état, et sa fonction est reprise ailleurs.** > > **Pourquoi.** Le lipsync décrit ici repose sur les *word timestamps* de **Google Cloud TTS** > (`enable_time_pointing`, voir plus bas). Or le code livré tourne sur **Gemini TTS** > (`GeminiTtsEngine`, `gemini-2.5-flash-preview-tts`, voix Sulafat / Umbriel) : **il n'existe aucune > source de timestamps**. Le plan n'est pas « à faire », il est sans fondation. > > **Ce qui le remplace.** Le **portrait canon** d'un `Persona` (voir > [studio-plan.md §3.8](studio-plan.md)) donne déjà un visage à afficher à côté du lecteur audio — > l'essentiel de la valeur perçue, pour zéro travail supplémentaire. Si du mouvement est voulu plus > tard, une **boucle vidéo de 6–8 s** (Kling 3.0 / Veo 3.1, lot 10 du plan Studio) est un meilleur > produit qu'un lipsync 3 frames. > > **Ce qui reste vrai et a été récupéré dans `studio-plan.md`** : générer des vues d'un même > personnage en réinjectant la première en référence. C'est exactement le mécanisme du canon en > **jeu de vues** de `Persona` — ce plan l'avait trouvé avant, sur un cas particulier. > > Conservé pour l'historique de décision. **Ne pas implémenter.** --- # Avatar Parlant (Talking Head) — Plan d'intégration > **Contexte** : Delta technique #6 issu de `myinfomate-ai-persona-analysis.md`. > Feature V2 — app mobile et borne uniquement. Hors scope smart glasses (pas d'écran). --- ## Concept Portrait 2D animé par lipsync synchronisé au TTS pré-généré ou dynamique. 3 frames PNG par persona, animées côté Flutter selon les timestamps retournés par Google Cloud TTS. --- ## Assets par persona | Frame | État bouche | Usage | |---|---|---| | `frame_0.png` | Fermée | Idle, fin de phrase, consonnes labiales (M, B, P) | | `frame_1.png` | Mi-ouverte | Consonnes courantes, transition | | `frame_2.png` | Ouverte | Voyelles (A, E, I, O, U) | ### Modèle de génération — À tester Deux candidats dans l'écosystème Google (même billing GCP que Gemini et Cloud TTS) : | Modèle | Prix/image | 3 frames | Notes | |---|---|---|---| | **Gemini 2.5 Flash Image** | $0.039 | ~$0.12 | Bon rapport qualité/prix | | **Gemini 3 Pro Image** | $0.134 | ~$0.40 | Meilleure qualité, meilleure consistance de style | **Test à faire** : générer les 3 frames d'un même personnage avec chaque modèle et comparer la **cohérence de style entre les frames** (critère numéro 1 pour un lipsync crédible). Si Gemini 3 Pro est significativement plus consistant, le surcoût de $0.28 par persona est négligeable. Par défaut dans le code : **Gemini 2.5 Flash Image**, configurable via constante pour switcher facilement. ### Prompts de génération Trois appels séquentiels — les prompts 2 et 3 **doivent** envoyer l'image de référence (frame 0) pour garantir la cohérence visuelle. **Prompt 1 — Base (bouche fermée)** ``` 2D cartoon illustration of a friendly [description du persona], warm smile, mouth closed, facing slightly to the right, bust portrait, clean white background, consistent art style, flat colors, soft shading. Reference sheet style. ``` **Prompt 2 — Mi-ouverte** *(+ image de référence)* ``` Same character as the reference image, exact same art style, same colors, same angle, same lighting, mouth slightly open as if mid-speech. ``` **Prompt 3 — Ouverte** *(+ image de référence)* ``` Same character as the reference image, exact same art style, same colors, same angle, same lighting, mouth open as if speaking a vowel sound. ``` ### Coût - Gemini 2.5 Flash : ~$0.12 par persona (one-shot) - Gemini 3 Pro : ~$0.40 par persona (one-shot) --- ## Stockage Firebase ``` {instanceId}/personas/{wakewordId}/frame_0.png ← bouche fermée {instanceId}/personas/{wakewordId}/frame_1.png ← mi-ouverte {instanceId}/personas/{wakewordId}/frame_2.png ← ouverte ``` Les URLs sont stockées dans la config du persona (aux côtés de `VoiceName` et `PersonaPrompt`). --- ## UX dans le CMS (manager-app) Dans la page "Configuration du guide IA", section par persona : 1. Champ `PersonaPrompt` (description du personnage : "chevalier médiéval jovial") 2. Bouton **"Générer l'avatar"** → appel backend → DALL-E 3 × 3 → upload Firebase → prévisualisation des 3 frames 3. Possibilité de re-générer (coût ~$0.12 à chaque fois, à afficher clairement) 4. Prévisualisation : animation en loop des 3 frames dans le CMS pour validation --- ## Lipsync Flutter ### Mode simple — loop (V2 MVP) ```dart // Pendant la lecture audio : boucle les 3 frames Timer.periodic(Duration(milliseconds: 90), (timer) { if (!isPlaying) { setState(() => currentFrame = 0); timer.cancel(); return; } setState(() => currentFrame = (currentFrame + 1) % 3); }); ``` ~30 lignes, zéro dépendance. Suffisant pour une première version convaincante. ### Mode avancé — word timestamps (V2+) Google Cloud TTS avec `enable_time_pointing: SSML_MARK` (ou `WORD`) retourne des timestamps par mot. Mapping côté Flutter : ```dart String getFirstSignificantChar(String word) => word.toUpperCase().trimLeft()[0]; int frameForWord(String word) { final c = getFirstSignificantChar(word); if ('MBP'.contains(c)) return 0; // bouche fermée if ('AEIOU'.contains(c)) return 2; // bouche ouverte return 1; // mi-ouverte } ``` À chaque timestamp : `setState(() => currentFrame = frameForWord(word))`. > Note : `enable_time_pointing` retourne des timestamps au niveau du **mot**, pas du phonème. Le mapping par première lettre est une approximation raisonnable — suffisant visuellement à la vitesse de lecture normale. --- ## Intégration avec le TTS pré-généré Pour le contenu pré-généré (articles, POIs), les timestamps sont générés **en même temps que le MP3** et stockés à côté : ``` {instanceId}/tts/article/{sectionId}/{wakewordId}/{lang}.mp3 {instanceId}/tts/article/{sectionId}/{wakewordId}/{lang}.json ← timestamps ``` Le JSON contient la liste `[{word, startTime, endTime}]` — Flutter le charge une fois et l'utilise pour l'animation. Pour les **questions libres** (TTS dynamique), les timestamps sont retournés en même temps que l'audio dans la réponse de l'endpoint `/ask`. --- ## Dépendances avec les autres deltas | Delta | Lien | |---|---| | #2 — Persona config | `PersonaConfig` stocke les URLs des 3 frames + le `PersonaPrompt` utilisé pour DALL-E | | #4 — TTS pré-généré | Génère le MP3 + timestamps en même temps ; même job Hangfire | | #3 — Endpoint `/ask` | Retourne audio + timestamps pour questions libres | | #5 — Canal Flutter | Intègre le widget Talking Head ; smart glasses = hors scope |