Tuto VideoIA

Comment on fabrique une présentatrice JT de A à Z !

Chaque semaine, GlorieuxGeek.com publie un JT vidéo de 1 à 2 minutes, présenté par une avatar IA qui résume l’actualité du moment. Pas de tournage, pas de monteur, pas de community manager qui veille tard pour publier à l’heure : tout est généré, monté et diffusé automatiquement. Dans cet article, on lève le capot sur la chaîne complète qui permet d’obtenir ce résultat, étape par étape, avec les outils utilisés, les choix techniques et les pièges qu’on a rencontrés en cours de route.

Spoiler : la quasi-totalité de la chaîne tourne sur un PC grand public (Intel Core i5-11400F, RTX 3060 12 Go, 48 Go de RAM), avec seulement deux maillons qui passent par le cloud.

Vue d’ensemble du pipeline

Avant de plonger dans le détail, voici la chaîne complète, dans l’ordre :

  1. Sélection des sujets : récupération des articles de la semaine sur WordPress, triés par popularité réelle
  2. Écriture du script : génération du texte du JT (intro, sujets, outro, bandeau) par une IA de langage
  3. Voix off : synthèse vocale de chaque section du script
  4. Vidéo de la présentatrice : génération d’un clip animé de la présentatrice via IA vidéo, bouclé pour durer aussi longtemps que nécessaire
  5. Synchronisation labiale (lip-sync) : la bouche de la présentatrice est resynchronisée sur la voix off générée, en local sur GPU
  6. Montage final : superposition du bandeau d’actu, du logo et des visuels d’articles, au bon moment, avec FFmpeg
  7. Publication automatique : envoi de la vidéo finale sur les réseaux sociaux

Chaque étape est scriptée en Python et orchestrée par un seul programme, lancé une fois par semaine.

Étape 1 — Choisir les bons sujets, automatiquement

Le pipeline part à la pêche aux articles publiés sur le site dans les 7 derniers jours, via l’API REST de WordPress. Mais publier les articles les plus récents n’est pas forcément publier les plus pertinents : on trie donc le pool d’articles candidats par nombre de vues réel, lu directement sur chaque page (le thème du site affiche un compteur de lecture en façade, pas besoin de token ou d’API analytics externe).

Un detail qui a son importance : un article peut avoir beaucoup de vues mais un angle devenu obsolète. Exemple typique rencontré en pratique : un article titré « à sept jours du Mondial » publié juste avant le début de la Coupe du monde… et toujours en haut du classement une semaine plus tard, alors que la compétition a déjà commencé. Le sujet de fond reste valable, mais le cadrage temporel (“on attend que ça arrive”) ne correspond plus à la réalité.

Pour filtrer ce genre de cas, on envoie la liste des articles candidats (titre, date de publication, résumé) à un modèle de langage, avec une consigne précise : repérer les articles dont le cadrage temporel est devenu incohérent par rapport à la date du jour, sans pénaliser les articles simplement “un peu anciens”. Le modèle répond par un verdict structuré (JSON) article par article, et les articles obsolètes sont écartés du classement.

Résultat : sur un pool d’une trentaine d’articles, le système retient les meilleurs candidats (jusqu’à 5) pour la vidéo, et les suivants pour le bandeau d’actu défilant.

Étape 2 — L’IA rédactrice en chef

Une fois les sujets retenus, place à l’écriture. On envoie à Claude (le modèle d’IA d’Anthropic) les résumés des articles sélectionnés, avec un brief de “rédactrice en chef” très cadré :

  • une accroche d’intro percutante, sans “Bonjour” générique
  • une présentation orale de chaque article, 15-20 secondes, ton factuel et journalistique
  • une outro qui mentionne GlorieuxGeek.com — et uniquement à ce moment-là (les sections précédentes n’ont pas le droit de citer le site, pour ne pas alourdir le discours)
  • un résumé pour le bandeau défilant, qui couvre les autres articles de la semaine (ceux qui n’ont pas leur place dans la vidéo)

Le tout est demandé en JSON strict, ce qui permet de récupérer directement une structure exploitable par le reste du pipeline : intro, article1, article2outro, ticker.

Étape 3 — Donner une voix au script

Chaque section du script est ensuite envoyée à ElevenLabs, un service de synthèse vocale, qui renvoie un fichier audio par section avec une voix française naturelle. Quelques réglages ont été affinés au fil des essais : stabilité, “style” de la voix, et surtout la vitesse d’élocution — un paramètre crucial puisqu’il détermine directement combien de mots peuvent rentrer dans une vidéo de durée donnée.

Ici intervient un mécanisme important : la génération adaptative. Plutôt que de générer un nombre fixe d’articles, le pipeline génère l’intro et l’outro d’abord (pour connaître leur durée), puis génère les articles un par un, en cumulant la durée totale. Dès que la durée cumulée (articles + outro) atteint la cible (par exemple 1 min 20), et qu’un minimum d’articles a été couvert, on s’arrête — sans générer (ni payer) pour des articles supplémentaires qui ne seraient pas utilisés. Si on atteint le maximum d’articles prévu sans avoir atteint la durée cible, on s’arrête aussi, avec un avertissement dans les logs.

Concrètement, sur une semaine donnée, le JT peut faire 3 articles (~89 secondes) ou 4 articles (~87 secondes) selon la longueur naturelle des résumés générés — le système s’adapte tout seul.

Tous les fichiers audio des sections retenues sont ensuite concaténés en une seule piste, avec une table de timing précise : à quelle seconde commence et finit chaque section. Cette table sera réutilisée pour synchroniser les visuels d’articles dans le montage final.

Étape 4 — Faire “bouger” la présentatrice

C’est ici qu’intervient la partie la plus spectaculaire : générer une vidéo de la présentatrice qui bouge, gesticule, sourit — sans tournage.

On utilise Kling (via la plateforme Replicate), un modèle de génération vidéo par IA, en mode image-to-image : on lui fournit une image de départ et un prompt décrivant le mouvement attendu (hochements de tête, mains qui reviennent en position de repos, sourire confiant, bouche qui articule…).

Le piège du “clip qui boucle mal” est résolu avec une astuce de montage assez simple mais efficace :

  1. On génère un premier clip (5 secondes) à partir d’une image de base
  2. On extrait la dernière frame de ce clip, et on l’utilise comme image de départ du clip suivant
  3. On répète l’opération pour obtenir 4 clips chaînés (A → B → C → D), qui s’enchaînent visuellement sans à-coup
  4. On concatène ces 4 clips dans l’ordre (ABCD), puis on génère leur version inversée (DCBA) avec un simple flip temporel
  5. On colle ABCD + DCBA : on obtient une unité de boucle de ~40 secondes qui part et revient à son point de départ visuel — donc qui peut être répétée à l’infini sans coupure visible

Cette unité de 40 secondes est ensuite bouclée autant de fois que nécessaire (via le concat de FFmpeg) pour couvrir la durée totale du JT (89 secondes, 2 minutes, peu importe) — avec une marge d’1 seconde pour ne jamais manquer de matière lors du montage final.

À ce stade, on a une vidéo de présentatrice qui bouge naturellement, sans audio, qui dure exactement ce qu’il faut.

Étape 5 — La synchronisation labiale, en local

C’est l’étape la plus gourmande en calcul, et celle qui a connu le plus d’itérations. L’objectif : faire correspondre les mouvements de bouche de la présentatrice à la voix off générée à l’étape 3.

Le choix s’est porté sur MuseTalk (modèle open-source de TMElyralab), installé en local dans un environnement Python dédié, avec les poids des modèles (détection de visage, segmentation, encodeur audio Whisper, VAE…) téléchargés depuis Hugging Face.

Le fonctionnement, en résumé :

  • MuseTalk analyse chaque frame de la vidéo de la présentatrice pour détecter le visage et ses repères (landmarks)
  • Il analyse l’audio pour en extraire les unités phonétiques
  • Il régénère la zone de la bouche, frame par frame, pour qu’elle corresponde au son

Pour ~90 secondes de vidéo (à 24-25 images par seconde, soit plus de 2200 frames), le traitement complet prend environ 25 à 30 minutes sur une RTX 3060 : environ 1 minute pour la lecture des frames, 11-12 minutes pour la détection des visages, 4-5 minutes pour l’inférence proprement dite, et 9-10 minutes pour réassembler les frames générées en vidéo.

Premier verdict après test sur une vraie vidéo Kling (mouvements de tête, ping-pong, donc bien plus complexe qu’une simple tête parlante statique) : la qualité est au rendez-vous. Le résultat est nettement supérieur à l’alternative testée auparavant (Wav2Lip), avec des mouvements de tête et des expressions préservés en plus du lip-sync.

Le piège de l’encodage Windows

Un bug particulièrement vicieux est apparu lors de l’intégration dans le pipeline automatisé : alors que le traitement fonctionnait parfaitement en lançant la commande “à la main” dans un terminal, il plantait systématiquement après 15 minutes une fois lancé depuis le script Python automatisé — juste après l’étape de détection des visages, sans produire de fichier de sortie.

La cause : MuseTalk affiche dans sa sortie standard un message contenant des caractères japonais (「268」, des chevrons typographiques utilisés pour encadrer un nombre). Quand cette sortie est redirigée (capturée par le script parent, ce qui est nécessaire pour récupérer les logs), Windows utilise par défaut un encodage de caractères (cp1252) qui ne sait pas représenter ces caractères — et le print plante. MuseTalk catche l’erreur en interne, l’affiche… et s’arrête sans avoir produit de vidéo, mais en rendant un code de sortie “succès” (0), ce qui rend le bug d’autant plus difficile à détecter automatiquement.

La solution : forcer l’environnement du sous-processus à utiliser l’UTF-8 (PYTHONIOENCODING=utf-8), et ajouter une détection explicite de ce message d’erreur dans les logs — même quand le code de sortie indique un succès — pour ne jamais laisser passer un échec silencieux.

Étape 6 — Le montage final

À ce stade, on dispose de :

  • une vidéo “présentatrice + voix synchronisée” (issue de MuseTalk)
  • les images mises en avant de chaque article retenu
  • le texte du bandeau d’actu défilant
  • la table de timing de chaque section

Le montage final est entièrement réalisé avec FFmpeg, via un graphe de filtres (filter_complex) qui empile plusieurs couches :

  • la vidéo de la présentatrice, redimensionnée au format vertical 1080×1920 (format Reels/Shorts)
  • un bandeau “ACTUALITÉS” généré dynamiquement avec Pillow (fond sombre, liseré doré)
  • un texte défilant (le ticker), avec gestion des caractères spéciaux qui posent problème à FFmpeg (le % notamment, qui casse silencieusement le rendu du texte et doit être remplacé par le mot “pourcent”)
  • le logo du site, en incrustation
  • les visuels des articles, affichés uniquement pendant la fenêtre temporelle de l’article correspondant — c’est là que la table de timing de l’étape 3 entre en jeu : chaque image a une condition enable='between(t, début, fin)' qui la fait apparaître et disparaître au bon moment

Un détail d’apparence mineur mais important : le positionnement vertical de ce bloc (bandeau + logo + images) doit être suffisamment haut pour rester dans la zone visible sur mobile, mais suffisamment bas pour ne pas chevaucher le visage de la présentatrice — un compromis qui dépend du cadrage du clip généré par l’IA vidéo, et qui a nécessité plusieurs essais pour être calé correctement. Pour faciliter ces réglages, le pipeline inclut un mode “test montage” qui permet de rejouer uniquement cette étape (quelques secondes au lieu de l’heure complète du pipeline) en réutilisant les fichiers déjà générés — bien utile pour itérer sur le positionnement sans tout relancer.

Le rendu final utilise l’encodage matériel NVENC de la carte graphique (bien plus rapide que l’encodage logiciel), avec un repli automatique sur l’encodage CPU si le matériel n’est pas disponible.

Étape 7 — Publication automatique

La vidéo finale est ensuite envoyée automatiquement sur Facebook et Instagram (Reels), via l’API Graph de Meta — avec un titre, une description et des hashtags génériques réutilisables d’une semaine à l’autre. Sur le compte concerné, le republiage croisé Reels Instagram → Facebook est activé, ce qui permet de couvrir les deux plateformes même quand l’API de publication directe sur Facebook est limitée par les politiques de vérification de Meta.

Bilan : combien de temps, pour quel résultat ?

Pour un JT d’environ 1 minute 30, le pipeline complet tourne en 50 à 60 minutes, répartis grossièrement ainsi :

  • sélection des articles + script + voix : quelques minutes
  • génération des 4 clips vidéo de la présentatrice (cloud) : ~10 minutes
  • synchronisation labiale (local, GPU) : ~25-30 minutes
  • montage final + publication : quelques minutes

Le tout est lancé en une seule commande, en tâche planifiée hebdomadaire — pas d’intervention manuelle nécessaire, sauf pour la relecture ponctuelle des logs.

Ce projet illustre bien ce qu’on peut faire aujourd’hui en combinant plusieurs IA spécialisées : un modèle de langage pour l’écriture, une IA vocale pour la voix, une IA vidéo pour l’animation, et une IA de lip-sync pour la cohérence audio-visuelle — chacune excellente dans son domaine, mais aucune ne faisant le travail complet seule. L’essentiel du savoir-faire réside dans la plomberie : la table de timing qui relie l’audio au montage, le système de boucle pour la vidéo de la présentatrice, et une bonne dose de gestion d’erreurs pour que le pipeline ne s’arrête pas en silence au milieu de la nuit.

Et comme souvent avec l’IA appliquée à des cas concrets : les bugs les plus coriaces ne viennent pas des modèles eux-mêmes, mais des détails d’intégration — dans ce cas précis, un problème d’encodage de caractères entre deux bouts de code qui, chacun pris séparément, fonctionnaient parfaitement.

Retrouvez le JT GlorieuxGeek chaque semaine sur nos réseaux sociaux.


En savoir plus sur Glorieux Geek

Subscribe to get the latest posts sent to your email.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *