Faceless Shorts
Vous créez un short vertical fini à partir d'un sujet : script, voix, sous-titres synchronisés mot par mot, plans animés, son et musique, rendu en MP4. Tout est code : dessin sur canvas, capture headless Chrome, ffmpeg, une voix Kokoro locale, un minutage local Whisper des mots, numpy pour le son. Pas d'images ou de vidéos IA, pas de clés API, pas de crédits supplémentaires.
SKILL = le dossier dans lequel se trouve ce fichier. Les projets se trouvent dans ~/faceless-shorts/<nom-du-short>/.
Un seul style : Mascot Explainer (mascot-explainer). VOUS en tant que mascotte cartoon plate (dessinée en code à partir d'une photo, riggée, synchronisée labialement) présentant « N étapes rapides » : une carte à la fois, des tuiles numérotées qui claquent dans un badge de coin, une liste de contrôle en direct, des légendes de titre mot par mot, tremblement de la caméra + un son à chaque impact. 30-45 s · 9:16. Idéal pour des tutoriels, astuces, « N étapes pour… », explicateurs tech / argent / productivité où le créateur est la marque.
Le style = styles/mascot-explainer/style-sheet.png (le rendu en une image, dessiné par son propre code) + STYLE.md (les règles + le manuel du moteur) + example/ (un projet complet qui se rend tel quel). Lisez STYLE.md en entier avant de planifier.
0. Première utilisation sur un ordinateur
bash SKILL/scripts/setup.sh jusqu'à ce qu'il affiche All set (vérifie Node 22+, ffmpeg, Chrome ; construit ~/.faceless-shorts/venv ; télécharge la voix Kokoro ~340 Mo et Whisper small.en ~0,5 Go). Installez tout ce qui manque de la manière officielle et gratuite, et demandez avant tout ce qui nécessite un mot de passe. Ensuite, bash SKILL/scripts/selftest.sh doit afficher SELFTEST PASSED : ouvrez la feuille de contact et notez ses noms et regardez-les.
1. Prise d'informations (UN SEUL message, valeurs par défaut remplies)
Demandez uniquement ce qui est inconnu, tout à la fois : sujet (ou « trouve 3 idées »), un lien vers un short dont le format leur plaît (facultatif), durée (par défaut ~30 s), voix (SKILL/scripts/py SKILL/scripts/voice.py --list ; par défaut am_michael), mode voix off : voix AI (par défaut) · leur propre enregistrement (ils enregistrent après avoir vu le script ; words.py --audio) · sous-titres seuls (pas de voix encore ; estimate.py), musique (fond intégré · aucune · leur propre fichier libre de droits), ligne de fin / pseudo, et une photo nette de face d'eux (facultative) et une tenue, ou le nom d'une mascotte enregistrée dans ~/faceless-shorts/_mascots/. « Go » = les valeurs par défaut.
2. Le plan (UN ÉCRAN, puis attendez)
Affichez : titre · la narration complète, une ligne par plan, avec ses fragments de légende (1. Regardez la | vraie *adresse de l'expéditeur) · la liste des plans, une ligne chacun (ce que l'on voit, ce qui bouge, sur quel mot cela arrive) · les nouveaux composants que vous ajouterez au kit, le cas échéant · les faits et leurs sources. Demandez « On le construit ? » et attendez.
Règles du script. Écrivez-le comme une personne parle réellement à un ami : des phrases complètes et fluides avec des mots de liaison (« Bon, », « où », « mais », « donc », « ce qui signifie »), pas une liste de courtes déclarations sous forme de légendes. ~90-110 mots pour 35 s.
Une ligne est un PLAN, pas une phrase : divisez chaque phrase en 1-3 lignes aux pauses naturelles (virgules, « et », « où »), de sorte que l'image change toutes les 1,5-3,5 s tandis que la voix continue de couler (voice.py dit chaque phrase entière d'un seul coup). Forme : un accroche avec un vrai chiffre sourcé, une promesse en une ligne, 3-6 étapes qui commencent par « Un, … », une action de fin claire. Écrivez les nombres comme ils sont dits (« sept »). Lisez-le à voix haute dans votre tête : si cela ressemble à des légendes, réécrivez-le.
Écriture originale uniquement : prenez un format qui vous plaît, jamais le script ou les plans d'un autre créateur. Chaque fait est vérifié par rapport à une source fiable (listez-les dans script.json « sources »).
3. Construction
bash SKILL/scripts/new_video.sh mascot-explainer <nom-du-short>copie l'exemple dans~/faceless-shorts/<nom-du-short>/.- Écrivez
script.json(lignes + légendes + intervalles ; voir STYLE.md). Créez d'abord la mascotte (mascot.json, STYLE.md §2), rendez sa feuille de poses et obtenez l'accord de l'utilisateur avant d'écrire des plans. - Minutage :
SKILL/scripts/py SKILL/scripts/voice.py <proj>puisSKILL/scripts/py SKILL/scripts/words.py <proj>(propre enregistrement :words.py <proj> --audio their.m4a; sous-titres seuls :estimate.py <proj>). - Réécrivez
src/shots.js: un plan par ligne (ou deux pour les lignes longues), chacun placé aveccut(i)et ses moments clés sur les mots avecWd('mot', ligne). Réutilisez le kit (src/core/kit.js) ; ajoutez-y de nouveaux composants, dans le style du rendu. - Dans le projet :
node tools/capture.mjs check(doit dire CHECK OK) →node tools/capture.mjs cues→SKILL/scripts/py tools/mix.py .→ QA (section 4) →node tools/capture.mjs video renders/<nom>.mp4. Itération sur un plan :node tools/capture.mjs frames review/f "4.2,4.6"et regardez.
4. QA : ne montrez jamais une image que vous n'avez pas regardée
node tools/capture.mjs sheet review/all.jpg 0.5 10 (une image toutes les 0,5 s, horodatée) et lisez toute la feuille, puis les images clés en taille réelle. Pour chaque image, demandez :
- Est-ce que cela a du sens ? Une carte à la fois ; la pose de la mascotte correspond à la ligne ; les accessoires bougent avec ce qui les tient. Rien n'apparaît avant sa cause.
- Correspond-il à la narration à ce moment-là ? L'image change juste avant sa ligne ; les révélations arrivent sur leur mot.
- Y a-t-il des collisions ? Les bras, les tampons et les éclats ne croisent jamais le titre, la carte, le badge, la liste de contrôle ou les uns les autres accidentellement.
- Légendes : 1-4 mots, au plus un mot d'accent violet, correctement orthographié, jamais affiché avant que le mot ne soit prononcé.
- Feuille de style : seulement la palette, les formes plates, les ombres d'encre dures, le rouge uniquement pour le danger.
- Son : voix claire par-dessus la musique ; effets doux (pas de tic ou de bip agressifs). Corrigez, re-rendez la feuille, revérifiez. Dites à l'utilisateur ce que vous avez détecté et corrigé.
5. Livraison
Ouvrez le MP4 pour l'utilisateur. Donnez aussi : une copie de partage si > 35 Mo (ffmpeg -i in.mp4 -c:v libx264 -crf 21 -preset slow -c:a aac -b:a 160k -movflags +faststart share.mp4), la meilleure image de couverture (capture.mjs frames), un titre, une légende et 5-8 hashtags.
Pour le mode propre enregistrement, donnez-leur aussi le script avec le minutage de chaque ligne à lire. Offrez un tour de modifications précises et ne re-rendez que ce qui a changé.
5b. Publier sur YouTube via Zapier (uniquement lorsque l'utilisateur demande à télécharger)
Tous les appels sont des outils en mode Code : exécutez-les à l'intérieur de execute avec tools.zapier.* (ne les appelez pas comme des outils normaux). Validé une fois dans un vrai téléchargement ; les valeurs ci-dessous sont exactes.
- Connectez-vous. Si
list_zapier_skillsa une compétence enregistrée pour le téléchargement, utilisez-la. Sinon, assurez-vous que l'application YouTube est activée :discover_zapier_actions({ app: "YouTube" })→enable_zapier_action({ selected_api: "YouTubeV4CLIAPI", app_display_name: "YouTube", action: "upload_video" }). Si aucune connexion n'existe encore,manage_zapier_connections({ selected_api: "YouTubeV4CLIAPI" })renvoie une URL de connexion pour l'utilisateur. - Hébergez le fichier. Les paramètres
video/thumbnailde l'action nécessitent une URL que les serveurs de Zapier peuvent récupérer ; un chemin local est silencieusement erroné. Placez le MP4 sur un hébergement temporaire, dans cet ordre (tous testés le 2026-11-03 ; sur Windows utilisezcurl.exe) :- a. litterbox (expiration de 1 h à 72 h, jusqu'à 1 Go) :
curl -F "reqtype=fileupload" -F "time=1h" -F "fileToUpload=@renders/<nom>.mp4" https://litterbox.catbox.moe/resources/internals/api.php→ renvoie l'URL directe sous forme de texte brut. - b. uguu.se (expiration d'environ 3 h, bon pour les shorts sous 35 Mo) :
curl -F "files[]=@renders/<nom>.mp4" https://uguu.se/upload→ renvoie du JSON ; utilisezfiles[0].url(le liend.uguu.se/...). - c. catbox (permanent, sans expiration) : même appel que (a) sans
-F "time=1h". Public pour toujours, donc seulement avec l'accord de l'utilisateur. - Ignorez ceux-ci (vérifiés cassés le 2026-11-03, ne gaspillez pas de tentatives) : 0x0.st (téléchargements désactivés), tmpfiles.org (le lien est une page de visualisation, pas le fichier brut), gofile.io (le téléchargement brut nécessite un jeton de compte), file.io (l'API curl redirige vers son application web), bashupload.com, temp.sh (mort).
- Vérifiez toujours l'URL avant de l'utiliser :
curl -sSI <url>doit renvoyer 200/206 avec un type de contenu vidéo. Ne faites jamais confiance au JSON d'un hôte sans vérification. - Dites à l'utilisateur que cela met sa vidéo sur un hôte temporaire public qui expire automatiquement.
- a. litterbox (expiration de 1 h à 72 h, jusqu'à 1 Go) :
- Confirmez d'abord. Cela écrit sur la vraie chaîne de l'utilisateur, donc confirmez avant l'exécution : titre, visibilité (privée / non listée / publique) et catégorie.
Résolvez
category_idavecinspect_zapier_actions({ tool_name: "youtube_upload_video", enum_property: "category_id" })si nécessaire. Éducation = 27 (par défaut pour les reels tutoriels), Comédie = 23, Comment faire & Style = 26. - Téléchargez.
execute_zapier_write_action({ selected_api: "YouTubeV4CLIAPI", action: "upload_video", tool_name: "youtube_upload_video", params: { video: "<URL temporaire>", title, description (terminez-la par #shorts), tags: [5-8 hashtags sans #], category_id: "27", privacy_status, made_for_kids: false, embeddable: true, notify_subscribers: true, default_language: "en", license: "youtube" } }) - Rapportez. Le résultat contient
id; le lien esthttps://www.youtube.com/watch?v=<id>. Une vidéo verticale de 60 s ou moins devient automatiquement un Short (pas de champ supplémentaire). Ouvrez le fichier local pour l'utilisateur (tools.browser.preview({ path: "renders/<nom>.mp4" })) et donnez l'URL YouTube en texte. Le navigateur intégré échoue souvent à charger youtube.com avec ERR_ABORTED ; cela ne signifie pas un échec du téléchargement. - Miniatures. Les téléchargements non listés n'acceptent pas de miniature personnalisée via cette action ; proposez l'image de couverture enregistrée si l'utilisateur rend la vidéo publique plus tard.
Jamais
Générez des images ou des vidéos avec de l'IA ; dépensez l'argent ou les crédits de l'utilisateur ; téléchargez sur YouTube ou un hôte sans que l'utilisateur ne le demande et ne confirme ; copiez le script, les plans ou les images d'un autre créateur ; écrasez un projet d'utilisateur sans demander ; livrez une image que vous n'avez pas regardée.