RolynTrotter/vibe-podcast

Créez des graphiques par épisode pour podcast à partir des modèles Apple Motion (carte titre principale, tiers inférieur de citation) et placez-les dans Final Cut Pro via FCPXML. À utiliser pour une carte titre, une citation/tiers inférieur, du texte à l'écran ou tout ce qui implique des fichiers .motn/.moti ou Motion.

Qu'est-ce que vibe-podcast ?

Ce skill automatise la production de graphiques pour chaque épisode d'un podcast en manipulant les fichiers Motion (format ozml) et en générant du FCPXML pour Final Cut Pro. Il contourne l'absence de scripting AppleScript ou de rendu CLI dans Motion 5.9 en traitant les fichiers .motn/.moti comme du XML et en déléguant le rendu à Final Cut Pro. Les outils principaux sont `motionkit.py` (inspection, modification de texte, keyframes, aperçu, installation de modèles) et `titles_fcpxml.py` (génération de projet FCPXML avec titres positionnés dans le temps). Il prend en charge deux modèles spécifiques : une carte titre principale (TF_Podcast_title) avec animation et un tiers inférieur de citation (Citation v2) avec plusieurs champs de texte. L'import sans clics dans FCP est validé via l'option `--library --push`. Le skill permet également de prévisualiser des images clés et d'inspecter l'animation complète (keyframes, comportements) pour retiming ou modifications programmatiques.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RolynTrotter/vibe-podcast/tree/HEAD/.claude/skills/motion-graphics

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

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

Documentation

Graphiques animés pour le podcast

Motion 5.9 n'a pas de dictionnaire AppleScript ni de rendu CLI. Tout ce qui suit fonctionne en traitant les fichiers Motion comme du XML (ozml), et en fournissant du FCPXML à Final Cut Pro qui référence les modèles de titres installés. C'est Final Cut qui effectue le rendu.

Les outils se trouvent dans agent-motion/ :

OutilFonction
motionkit.py inspect FILE [--json]Arborescence des couches, couches de texte (texte/police/taille/position), timing en secondes, ce qui est publié vers FCP, références médias
motionkit.py set-text IN OUT --set "KEY=TEXT" ...Réécrit les couches de texte. KEY = id de couche, nom de couche ou texte actuel. \n pour les sauts de ligne. Corrige les longueurs styleRun (UTF-16) pour que Motion ne dysfonctionne pas
motionkit.py keyframes FILE [--grep X] [--all]Chaque paramètre animé avec les temps/valeurs des images clés (la rotation est en radians)
motionkit.py preview FILE --at 1.9 3.2 [--open]Écrit des copies positionnées à ces instants ; --open les ouvre dans Motion en arrière-plan (open -g) pour une app_screenshot
motionkit.py install FILE --name NAMECopie un projet dans le dossier Titres de Motion en tant que modèle de titre FCP
titles_fcpxml.py SPEC.json -o OUT.fcpxmlListe de repères → Projet FCPXML avec les titres aux bons moments, textes remplis

Les modèles de l'émission

Installés sous ~/Library/Containers/com.apple.motionapp/Data/Movies/Motion Templates.localized/Titles.localized/Templates/ (UID FCP : ~/Titles.localized/Templates/<Name>/<Name>.moti). Des copies des deux principaux se trouvent dans agent-motion/*.motn.

  • TF_Podcast_title : carte titre principale, 5 s, 29,97, 1080p. Couches de texte : Tiersias Foundation Podcast (affiche "Tiresias Foundation Podcast" ; le nom de la couche a une faute de frappe, continuez à l'utiliser comme clé) et Episode 4: Carl Schmitt (la ligne par épisode, Futura Medium). Il publie une Zone de dépôt.
  • Citation v2 : tiers inférieur pour citations et sources, PT Serif. Couches de texte : ~Author Lastname (italique ; l'émission préfixe avec ~), Person Writes Silly Headline to (titre de l'œuvre, peut être sur deux lignes), 20 Apr, 1969 (date), Publication.
  • Citation v2 no pub : identique sans la ligne de publication. Également Citation v1, Black/Orange/Yellow/PeeTitle, Minister_Types.

Utilisations passées (bibliothèques Podcast3/4) : Timothy Snyder, Carl Schmitt, Xunzi, ~Eric L. Hutton, trans., ~Armando Iannucci, dir., 95 U.S. 602. Les traducteurs et réalisateurs reçoivent un suffixe de rôle. Les affaires judiciaires vont dans le champ auteur.

Flux de travail

  1. python3 agent-motion/motionkit.py inspect "<template>.moti" pour obtenir les clés des couches de texte.
  2. Écrire un JSON de repères (voir agent-motion/examples/ep_demo.json) : template, at (secondes sur la timeline de l'épisode), duration optionnel, texts map.
  3. python3 agent-motion/titles_fcpxml.py cues.json -o titles.fcpxml, puis valider : xmllint --noout --dtdvalid <copie de FCPXMLv1_11.dtd> titles.fcpxml. Les DTD sont dans /Applications/Final Cut Pro.app/Contents/Frameworks/Interchange.framework/Versions/A/Resources/. Copiez-en d'abord une, car xmllint échoue sur le chemin avec des espaces.
  4. Pousser : ajoutez --library <bundle> --push (zéro clic). Sans --library, FCP affiche un sélecteur de bibliothèque, donc laissez cela à l'utilisateur. Les titres sont placés au-dessus d'un espace vide, pour pouvoir être copiés sur le montage réel.

Pour une carte unique intégrée (p. ex. une vignette ou une carte avec un changement de style que FCP ne peut pas modifier), utilisez set-text sur le .motn et open -g -a Motion OUT.motn pour que l'utilisateur l'examine ou l'exporte.

Validé dans FCP 11.0.1 (2026-10-18)

  • L'import sans clic fonctionne : titles_fcpxml.py cues.json -o x.fcpxml --library chemin/vers.fcpbundle --push ajoute <import-options> (emplacement de la bibliothèque, lier les assets, supprimer les avertissements) et l'envoie avec open -g. FCP importe en arrière-plan et crée la bibliothèque si elle est manquante. Utilisez une bibliothèque jetable sous scratch/fcp-test/ pour les tests, et jamais les vraies bibliothèques de l'utilisateur sans demander.
  • L'ordre de <text> = ordre des couches de texte dans le document Motion. Confirmé : l'auteur de Citation v2, le titre, la date et la publication atterrissent tous dans les bonnes cases.
  • Envoyez du texte brut (le défaut --style none). Ainsi le modèle conserve sa propre police, taille, couleur et ombre. --style font envoie une text-style-def avec famille/graisse/taille. Tout style def remplace le modèle, et les couches sans paramètre Size (Motion 48 par défaut) sont devenues minuscules avant que le fallback 48 soit ajouté. Utilisez --style font uniquement pour restyler délibérément.
  • La carte titre principale (TF_Podcast_title) s'importe avec son animation intacte.
  • Lisez l'état de FCP via app_screenshot sur com.apple.FinalCut : cliquez sur l'événement, puis sur l'icône du projet dans le navigateur (double-cliquer sur le nom démarre un renommage, donc appuyez sur Échap), puis sur la règle.

Visualisation et rendu (validé 2026-10-18)

  • Images de prévisualisation : motionkit.py preview FILE --at T --open, puis utilisez app_screenshot sur Motion (bundle com.apple.motionapp) en mode computer-use, puis zoomez sur le canevas. Fermez la fenêtre via app_menu File > Close. Saisir dans le champ de la tête de lecture de Motion depuis l'arrière-plan NE fait PAS bouger la tête de lecture. La copie <currentFrame> est la méthode fiable.
  • Rendu : computer-use ne peut pas cliquer sur File > Share (Export Movie, Save Current Frame). Demandez à l'utilisateur de cliquer sur Export. Le screencapture en shell manque de la permission d'enregistrement d'écran.
  • Ne jamais utiliser open -a sans -g. L'utilisateur travaille sur le même écran.

Animation (ce que le XML expose)

Les images clés sont curve > keypoint{time, value, in/out tangents} sous n'importe quel paramètre (Transform Position/Rotation/Scale, Blending Opacity, paramètres de filtre). Les comportements (Gather In, Pen Speed/Pressure) sont leurs propres nœuds avec des paramètres de timing et Controls. Ainsi nous pouvons lire la chorégraphie complète, et retimer, décaler ou ajouter des images clés par programmation. Ensuite prévisualiser-et-capturer pour vérifier. Chorégraphie de TF_Podcast_title : les figures Tiresias (Group 1/2) glissent de ±400 px à 1,5 s, puis oscillent ±10 px / ±2° jusqu'à 4,87 s. La paire d'images serpent apparaît à 1,74 s (échelle 0,17→0,62 à 2,1 s, masquée par des rectangles arrondis) et bondit entre les images clés à 2,1/3,17/4,14/4,87 s. La ligne de titre s'estompe à 1,5–1,7 s avec Gather In à partir de 1,0 s, et la ligne d'épisode Gather In à 2,37 s.

Notes sur ozml

  • Les temps sont "value timescale flags epoch" ; secondes = value/timescale.
  • Contenu texte : scenenode[factory=Text] > parameter[name=Object] > parameter[id=369] > text. Le style est styleRun style=ID offset length, donc un décalage de longueur casse le style.
  • Les factories en haut mappent factoryID → type (Text, Shape, Replicator, Image...). Les ids diffèrent par fichier, donc résolvez-les toujours via la table des factories.
  • La référence (ancienne, encore correcte pour l'essentiel) d'Apple : Motion XML guide sur developer.apple.com archive.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills associés