ccvideo — Vidéos promotionnelles produit de type Claude
Vous produisez une courte vidéo promotionnelle (20–45 s, 1920×1080 @ 30 ips) dans le langage visuel des vidéos de lancement d'Anthropic Claude : une toile de fond chaude couleur terre cuite, une fenêtre de terminal macOS exécutant une session Claude Code, du texte qui se tape et défile, de brefs mouvements de caméra entre des cadrages verrouillés, des cartes titres en police serif.
Prérequis
- Un projet Remotion doit exister. Si ce n'est pas le cas, en créer un :
npx create-video@latest --yes --blank --no-tailwind .puisnpm i. - Paquets (installer avec
npx remotion add <pkg>pour que les versions concordent) :@remotion/google-fonts,@remotion/transitions,zod(déclarez zod explicitement — la bibliothèque l'importe directement ; ne comptez pas sur le fait qu'il soit une dépendance transitive). - La bibliothèque de composants doit exister à
src/ccvideo/. Si ce n'est pas le cas, copiez tous les fichiers du répertoiretemplates/de cette compétence verssrc/ccvideo/. Ne réécrivez pas ces composants à partir de zéro. - Les outils de capture/vérification doivent exister dans
scripts/à la racine du projet. Si ce n'est pas le cas, copiez le répertoirescripts/de cette compétence (incluantscripts/lib/) à cet endroit. Tous les scripts résolventcaptures/par rapport au répertoire depuis lequel vous les exécutez, exécutez-les donc toujours depuis la racine du projet.
Vérité terrain (règles de contenu non-négociables)
Le contenu vidéo n'est jamais écrit à la main dans les composants de scène. Chaque fait montré — nombres, chemins, points d'accès, sorties de commandes, compteurs de lignes — doit provenir d'une capture de quelque chose qui a réellement été exécuté :
- Chaque vidéo a un répertoire
captures/<name>/contenant les artefacts bruts (réponses API, événements de session extraits) ainsi qu'unprops.jsonconstruit à partir d'eux de manière déterministe.props.jsonest la source de vérité unique que la composition rend. - Capture d'abord. Avant de réaliser la vidéo, exécutez la chose réelle :
node scripts/capture-xapi-cli.mjs— données X en direct via la CLI xapi (npx xapi-to, clé dans~/.xapi/config.json; la compétencexapidans.agents/skills/xapi/documente toutes ses capacités).node scripts/capture-x-user.mjs— variante X API officielle (nécessiteX_BEARER_TOKEN;--sampleécrit des données factices avecraw-meta.jsonmarquésample: true— ne publiez jamais une capture d'exemple).node scripts/transcript-to-props.mjs <session.jsonl> --prompt-match <str> --out captures/<name>— rejoue un tour réel d'une session Claude Code (les transcriptions se trouvent dans~/.claude/projects/<project-slug>/*.jsonl).- Nouvelle source de données ? Écrivez un nouveau script de capture suivant le même
schéma : récupérer la réalité → sauvegarder le brut → construire les props via un
constructeur déterministe partagé dans
scripts/lib/.
- Vérifiez avant de publier :
node scripts/verify-props.mjs captures/<name>reconstruit les props à partir des artefacts bruts et échoue en cas d'édition manuelle. Corrigez en recapturant, jamais en éditantprops.json. - Limite de relecture honnête : le rythme est une performance (vitesse de frappe, temps
de spinner), mais la capacité doit être réelle — la vidéo ne peut montrer que ce que
l'exécution capturée a réellement fait. Cela s'étend au chrome : les faits d'en-tête
de session (version de Claude Code, répertoire de travail) proviennent de la capture
(
claude --version, vrai cwd) ou l'en-tête est omis ; le compteur de jetons du spinner n'est rendu que lorsque la capture fournit une valeur réelle dethinkingTokens(sinon, uniquement les secondes). Les captures d'exemple échouent directement àverify-props(--allow-sampleexiste uniquement pour les tests de pipeline). - Les captures visent à pouvoir être commitées en toute sécurité, avec une défense en
profondeur — pas une garantie :
transcript-to-propsne persiste que les entrées que la vidéo utilise réellement (les lignes affichées des événements sélectionnés + leurs compteurs, une sortie de commande tronquée, les lignes de puces du résumé), nettoie les chaînes ressemblant à des secrets (clés API, Bearer tokens, identifiants d'URL, champs de mot de passe env/JSON, clés privées), et réécrit les chemins d'accueil normaux et aplatis en slug en~— le tout avant que les props soient construites, de sorte que les props, la vidéo et les archives brutes voient un contenu expurgé identique. Les listes de motifs ne peuvent jamais être complètes : examinez toujours une capture avant de la commiter, et considérez tout avertissement de rédaction comme un signal d'arrêt.
Flux de travail
- Capture d'abord (voir Vérité terrain) : produisez
captures/<name>/props.jsonà partir d'une exécution réelle. - Feuille de rythme à partir de la capture. Le texte de présentation (titres de cartes, mot de réflexion) se trouve dans les constantes/drapeaux du script de capture — choisissez l'unique prompt, le temps de code, la sortie d'exécution, les puces du résumé. Visez l'arc classique : code → créé → exécuté+sortie → résumé.
- Composez : enregistrez une
<Composition>danssrc/Root.tsxen utilisantGroundedVideodesrc/ccvideoavecschema={groundedVideoSchema},defaultPropsimporté duprops.jsonde la capture, etcalculateMetadatadérivant la durée viagroundedVideoDuration— les durées suivent le contenu automatiquement. Un travail de scène personnalisé au-delà de l'arc standard : construisez avec les primitives de la bibliothèque, mêmes règles. - Vérifiez avec des images fixes avant de déclarer terminé. Rendez une image fixe
par temps :
npx remotion still <CompId> --frame=<n> --scale=0.5 out.pnget regardez-les. Vérifiez : rien de coupé par la fenêtre du terminal (un avertissement de débordement[ccvideo]dans la sortie du rendu signifie qu'il faut tailler les temps), le timing semble sans hâte, les couleurs correspondent à la palette. - Exécutez
node scripts/verify-props.mjs captures/<name>, puis prévisualisez avecnpx remotion studio --no-open; rendu final avecnpx remotion render <CompId> out/<CompId>.mp4(ajoutez--props=captures/<name>/props.jsonpour rendre une capture différente sans toucher au code ; ajoutez--scale=2pour un master 4K comme les démos officielles — les compositions restent en 1920×1080 @ 30 ips dans le code).
Deux thèmes
Choisissez selon le produit, les deux partagent la marque terre cuite #D97656/#D97757 :
- Terracotta (par défaut) — toile chaude, session REPL Claude Code. Pour des
histoires d'agent/flux IA. Composants :
GroundedVideo/DataSession. - Dark (la grammaire de démo CLI
ant) — toile quasi noire#0B0B0B, terminal noir chaud#181716séparé seulement par une bordure subtile, invite de shell▶ ~/dir >(flèche#8B92C9, chevron#5FA97B), serif crème#D6D4CF. La structure est chapitrée : carte de marque pixel-logo → [carte interstitielle (tape mono + fine séparatrice + revendication serif) → temps de shell frais (taper une vraie commande, sortie réelle apparaît, invite idle revient)] par chapitre → outro de marque. Pour les produits CLI/outils développeur. Composants :DarkVideo/ShellBeat/InterstitialCard/WordmarkCard, palettedarkdanstheme.ts, schémadarkVideoSchema(construit à partir de captures comme le thème clair — par exempleprops-dark.jsonécrit parcapture-xapi-cli.mjs, vérifié parverify-props.mjs).
Le look (règles de style non-négociables)
- Toile
#CC7D5D, terminal#2B2C36, barre de titre#3A3634. Texte du corps#E3E4EB, atténué#9899A1, commentaires#6C6E6A, numéros de ligne#83848C. Accents : pervenche#B8B9F2(chemins, code en ligne, chaînes), sarcelle#85BEC5(mots-clés), or#F2C43D(flèches de statut). Tous définis danssrc/ccvideo/theme.ts— importez, jamais de codage en dur. - Polices : JetBrains Mono pour tout ce qui est terminal, Source Serif 4 pour les
cartes titres. Chargées dans
theme.tsvia@remotion/google-fonts, avec Noto Sans SC déjà ajouté comme fallback CJK pour les deux piles — les prompts en chinois sont rendus directement. - Fenêtre de terminal 1560×950 centrée (985 lorsqu'un en-tête
headerde session est affiché ; thème dark 1860×1010), rayon de 14 px, ombre douce et profonde, trois feux de circulation, texte de barre de titre monochrome qui reflète la tâche, par exempledev — · Implémente X — claude — 106×31. - La session Claude Code doit avoir l'air réelle : ligne d'entrée
>au-dessus d'une barre de statut dorée⏵⏵ mode auto activé (shift+tab pour cycler) · esc pour interrompre(les deux toujours visibles, épinglés en bas) ; un spinner✻ Cogitation…dans un emplacement de hauteur fixe juste au-dessus de la ligne d'entrée ; des puces de résultat d'outil●; un bloc de code numéroté se terminant par… +N lignes (ctrl+o pour développer); un résumé grasCe qu'il faitavec des puces-. - Caméra : pas de zoom ou de panoramique soutenu sur les scènes de terminal, jamais —
une mise à l'échelle fractionnée lente fait dériver et nager visiblement les petits
textes mono. Le seul mouvement de caméra autorisé est
<CutZoom>: des déplacements brefs et fortement atténués (~0,6 s) entre des cadrages autrement verrouillés — poussez dans le contenu dense, maintenez, reculez pour la révélation. Le texte ne peut être à mi-échelle que pendant un déplacement rapide délibéré, jamais pendant des secondes. Gardez la mêmeoriginsur le recul que sur la poussée pour que cela ne ressemble pas à un glissement latéral.DataSessionapplique cela automatiquement autour du tempsrun.<SlowZoom>reste réservé aux cartes titres. - Chrome d'authenticité de session (tous pilotés par schéma, tous optionnels) :
header(logo pixel +Claude Code vX+ ligne modèle/cwd, toujours visible),windowTitleIdle→ basculewindowTitleà la soumission du prompt, écho du prompt comme bloc surligné, spinner avec compteurs en direct(Ns · ↓ N tokens)et une ligne⎿ Astuce :optionnelle, barre de statut qui ajouteesc pour interrompreseulement en fonctionnement. Types de temps supplémentaires :answer(bloc de prose riche),alert(ligne surlignée en rouge), les tempstoolpeuvent porter des lignes enfants⎿. - Pas de dérive de transcription. Le texte du terminal ne peut apparaître qu'en fondu sur place : pas d'animations d'entrée positionnelles à l'intérieur de la fenêtre, et ne montez/démontez jamais un élément qui refond les lignes en dessous — les lignes transitoires (spinners, progression) vivent dans des emplacements de hauteur fixe afin que leur disparition ne déplace rien.
- Cartes titres : titre serif dans un quasi noir
#1F1508sur terre cuite, sous-titre mono à 68 % d'opacité, entrée en fondu. Titre ≥ 132 px, sous-titre ≥ 52 px à 1920 de large.
API des composants (src/ccvideo)
Couche pilotée par les données (préférée pour les vidéos entières) :
<GroundedVideo {...props}>— carte d'intro → session → carte d'outro, entièrement à partir d'une valeurgroundedVideoSchema(unprops.jsonde capture).<DataSession {...props.session}>— rend n'importe quelle valeursessionSchema: en-tête optionnel, frappe du prompt, spinner, puisbeats(union discriminée :code,tool,run,summary,answer,alert). Applique le cut-zoom du tempsrunautomatiquement ; avertit au moment du rendu si le contenu va déborder.sessionTiming(props, fps)/groundedVideoDuration(props, fps)— dérivation de timing pure ; utilisez danscalculateMetadata.<Rich segments>— rend les segments JSON{t: 'plain'|'kw'|'code'| 'comment'|'dim'|'bold', s}; le pont de props.json au texte stylé.
Primitives de présentation :
<TerminalWindow title width? height? variant?>— fenêtre sur la toile (variant="dark"pour le thème dark). Les enfants sont une colonne flex ; donnez à la transcriptionflex: 1pour que<InputBox>+<StatusBar>s'épingle en bas.<TypeText text from cps? cursor?>/<Cursor>— machine à écrire, 35–45 cps.<InputBox typedText? from? cps?>— ligne>; pas detypedText= curseur clignotant.<StatusBar mode? hint?>.<Thinking from? until? word? stats? tokens? tip?>— spinner ;statsaffiche en direct(Ns)— plus↓ N tokensseulement lorsquetokensporte un vrai compte capturé ;tipajoute une ligne⎿ Astuce :. Placez-le dans un emplacement de hauteur fixe entre la transcription et l'entrée ;untille fond en place.<Line from?>— une ligne de sortie, fondu d'entrée sur 8 images (opacité uniquement).<ToolLine from>— ligne de puce●.<CodeBlock from lines stagger? startLineNo? expandNote?>— lignes numérotées.- Étendues de tokens :
<K>mot-clé,<C>code/chemin,<Cm>commentaire,<Dim>,<B>. <SessionHeader version modelLine>,<PromptEcho>,<AlertLine from?>,<ToolChild from?>— chrome de session (voir règles de style).<CutZoom cuts={[{from, scale?, origin?, ease?}]}>— brefs déplacements atténués entre des cadrages verrouillés ; le seul mouvement de caméra autorisé sur les scènes de terminal.<SlowZoom from? to?>— cartes titres uniquement, jamais autour d'un terminal.<TitleCard title subtitle? titleSize?>.
Toute l'animation est pilotée par les images (useCurrentFrame + interpolate,
clampée, en ligne dans style). N'utilisez jamais CSS transition/animation.