real-sfx : des sons réels pour une vidéo animée
L'objectif : le film sonne comme si une personne disposant d'une bonne bibliothèque l'avait monté. Donc :
- Le son n'est jamais synthétisé. Sources : les bibliothèques de l'utilisateur (
config.json) et uisfx (un pack CC0 prêt à l'emploi de signaux d'interface, lui-même synthétisé : la seule exception, uniquement pour les moments d'interface ; "aucune synthèse" le désactive :--ui library). Aucun son adapté : le moment reste silencieux et est consigné dans le rapport. Cela remplace "aucune piste : synthétiser" des standards motion-standards. - Vous ne pouvez pas entendre. Le son est lu sous forme de chiffres, de mots et d'images (
references/listening.md). Ne présentez pas une sélection comme ayant été écoutée : dites ce qui a été vérifié visuellement et par mesure, et ce que l'utilisateur devrait écouter. - Conservez la musique et la voix lorsqu'elles portent le film. Le résultat est toujours une nouvelle MP4 et une piste WAV séparée.
- Ne doublez pas. La synthèse intégrée à l'audio du rendu est remplacée par les vrais sons, et non superposée en dessous (étape 1). La critique mesure cela sous forme de nombre (l'axe
doubling). - Ne modifiez ni le projet ni le dossier de la compétence. Placez tous les fichiers de travail dans votre propre dossier (
work/,result/).
À l'intérieur de Video Director
(Ajouté dans la copie de Video Director ; absent de l'original de Clipwing. UPSTREAM.md liste chaque modification.) Cette copie réside dans la compétence Video Director et est exécutée par son étape Sound : ../references/sound-stage.md, "Sound engineering". Ces étapes décident quels moments reçoivent un son, ne transmettent à cette compétence que ceux-ci (build/audio/sfx/events.json), épinglent les enregistrements choisis par l'utilisateur (sound_handoff.py pins), l'exécutent avec --ui library, --no-loudnorm et sans couche de texture ni fond sonore, et ne récupèrent que la piste d'effets et les repères résolus (sound_handoff.py collect). Suivez-les, et lisez ce fichier uniquement pour les options qu'elles ne couvrent pas. Définissez REAL_SFX_CONFIG, REAL_SFX_INDEX, REAL_SFX_TASTE, REAL_SFX_RATINGS, REAL_SFX_STEADY et REAL_SFX_STYLES vers des chemins sous ~/.config/real-sfx/ (le plugin installe chaque version dans un nouveau dossier, donc tout ce qui est écrit ici est laissé lors de la prochaine mise à jour), et n'utilisez pas --remember, qui écrit dans ce dossier (tout comme learn_style.py : copiez un style appris dans ~/.config/real-sfx/styles/).
Chemin rapide
D'abord python scripts/setup.py check (ffmpeg, bibliothèques principale/supplémentaires, index, uisfx) et
python scripts/look.py FILM.mp4 --out work/look (images avec le temps + le son original en dessous). Ensuite, selon ce que vous avez :
# 1. le projet a une liste d'événements (docs/cues.json, scripts/cues.json) OU un script qui synthétise son son (audio.cjs)
python scripts/from_cues.py PROJECT_FOLDER|docs/cues.json --video RENDER.mp4 --out work/cues.json
# 2. enregistrement d'écran sans liste : ui_events.py ... (references/screencast.md), puis from_cues.py work/ui/events.json
# 3. image uniquement : find_moments.py FILM.mp4 --out work/moments; suggest_cues.py work/moments/moments.json --out work/cues.json
# 3b. ANIMATION DOUCE COLORÉE sans liste (aperçu UI, illustration, graphiques animés) : l'automatisation voit 5-6 mouvements sur 40.
# étape 2, "Animation silencieuse sans liste" : find_moments.py FILM --out work/moments --fine; look.py FILM --at T --span 2.4
# --step 0.1 --out work/at.png; VOTRE PROPRE liste d'événements à partir des images (references/typed-cues.md) -> from_cues.py - --ui library
python scripts/mix.py work/cues.json --out result/film_sfx.mp4 --plan # quoi va où ; puis sans --plan
python scripts/critique.py result/film_sfx_resolved_cues.json result/film_sfx_sfx_track.wav
python scripts/levels.py result/film_sfx_resolved_cues.json result/film_sfx_sfx_track.wav --json work/edits.json
# un film dont le son est UNIQUEMENT des SFX (pas de musique ni de voix propre) : petits sons dans les trous, puis mix.py à nouveau (étape 4, "Couche de petits sons")
python scripts/texture.py work/cues.json --moments work/moments/moments.json
# le même film : un fond sonore (un long enregistrement réel sombre sous tout le film ; étape 4, "Fond sonore"), puis mix.py à nouveau
python scripts/bed.py work/cues.json [--list]
# chiffres contre neuf bobines SFX finies (étape 6, "Contre la référence") : pas de scores, n'affecte pas le verdict
python scripts/critique.py RESOLVED.json WAV --style clean-sfx-refs
# oreilles humaines à moindre coût (étape 6) : une page avec les questions de la critique et un verdict en un clic ; le modèle de masquage
python scripts/listen_page.py build work/listen --moments result/film_sfx.mp4 --critique RESOLVED.json WAV
python scripts/listen_page.py serve work/listen [--lan] # puis : listen_page.py results work/listen --log
python scripts/mix.py work/cues.json --out result/film_sfx.mp4 --masking # quels sons le reste cache (nécessite le venv)
Un dossier de projet trouve sa propre liste d'événements (docs/, scripts/, assets/) ; le script du synthétiseur n'est lu que lorsqu'il n'y a pas de liste. Choisissez tous les indicateurs de from_cues.py avant de modifier la feuille : l'exécuter à nouveau efface les modifications manuelles (puis sheet.py apply).
Voix dans le film : mix.py ... --voice-safe (profondeur normal ; --voice-depth light lorsqu'il y a de nombreuses textures silencieuses, deep uniquement pour les sons rares dans les pauses : il retire complètement l'interface du mix). La musique porte le film : --duck.
Loudness : une base reconstruite correspond à l'original par défaut ; votre propre : --target-lufs NUMBER.
Pas d'index, ou les bibliothèques ont été déplacées : python scripts/build_index.py, puis python scripts/listen.py tag-index.
Pas d'uisfx : setup.py init --uisfx. Un autre ordinateur : setup.py scan FOLDER, setup.py add-library NAME PATH [--tier main|extra] --index. Exécutez les scripts depuis le dossier de la compétence ; mettez entre guillemets les chemins avec des espaces ou des caractères non latins ; votre propre Python avec des chemins non latins sous Windows : PYTHONUTF8=1. Dans PowerShell, les guillemets cassent les arguments JSON : mettez-les dans un fichier.
D'où viennent les sons
| Ce qui est nécessaire | D'où cela vient |
|---|---|
| La base : whooshes, hits, risers, pops, carillons, touches, papier, bruitages, ambiance | la bibliothèque principale (tier: main, chemin dans config.json). Un pack trié avec catalog.json / catalog.csv donne à chaque son son type et son enregistrement source, ce qui évite de deviner à partir des noms de fichiers |
| Ce qui manque à la bibliothèque principale : chutes graves, pièces de monnaie, petits glitchs | bibliothèques de secours (tier: extra, marquées ~ dans les résultats) : uniquement lorsque la bibliothèque principale a moins de trois sons adaptés |
| Packs conçus avec leurs propres rôles | les rôles granular, atmosphere, power, music_transition, voice ne sont jamais demandés par la sélection automatique : prenez-les explicitement (--role, "pick": {"role": ...}) |
| Un moment d'interface : clic, tic, fenêtre, notification | uisfx (--ui auto) lorsque la liste elle-même nomme les types d'interface (clic, carillon...) : from_cues dit pourquoi et où (routes: key -> library:click, pop -> uisfx:select) |
| Frappe au clavier | toujours le vrai clavier de la bibliothèque, même avec --ui auto ; une séquence de 8+ événements click espacés de 35 à 170 ms est reconnue comme une frappe par from_cues lui-même (--no-typing-detect) |
| Contact physique : balle, pas, perle, objet | toujours la bibliothèque : une balle sur le sol fait un bruit sourd, pas un select (recette ci-dessous) |
Pas encore de bibliothèque : setup.py init --uisfx seul donne 78 signaux UI CC0. Sources gratuites d'enregistrements réels qui valent la peine d'être vérifiées (lisez chaque licence) : Freesound (filtre CC0), ensembles Sonniss GDC, Mixkit, Pixabay effets sonores.
"De ma bibliothèque", "aucune synthèse" ou "sons synthétiques" : --ui library. Un accent sur le logo ou un "cha-ching" dans un projet avec des sons d'interface uisfx : --from-library pop,bell (noms de types de la liste) ; pour un seul son : sheet.py set --at T --label bell id=65. Sous une musique tonale :
- les pas de hauteur des répétitions d'uisfx et des sons tonaux de la bibliothèque (carillon, pop, verre, pièce) se désactivent automatiquement lorsque le projet a une partition (
--ui-pitch off|cycle) ; - la hauteur d'un son réel est accordée aux notes de la musique :
mix.pyprend lamusic_refde la feuille (le fond sans effets, la piste de musique) ou--music-ref FILEet décale un son tonal par demi-tons entiers jusqu'à 2 plus les cents qui le mettent sur une note (2,5 au total), si cela le met sur une note ; le bruit est laissé intact (--no-tonal-fit;scripts/tonal.py SOUND --music FILE --at Tmontre les notes) ; - les intervalles des fréquences propres à l'auteur (
tick(t, 1800 * 2 ** (4 * i / 12))) deviennent les pas de hauteur du remplacement (melody:).
Flux de travail
1. Qu'y a-t-il déjà dans le son
look.py montre le spectrogramme du son natif (la voix est des bandes de phrases, la musique un tapis avec un battement, le silence est noir) ; listen.py voice FILM.mp4 donne la part de parole et de musique. Trois cas :
- La musique ou la voix de l'auteur : elles restent, les SFX vont par-dessus (
--duck/--voice-safe). Exception (réponse d'une personne sur un vrai film, 2026-10-19) : le film a été envoyé "pour être sonorisé", son son natif est uniquement de la musique (listen.py voice: parole 0 %), et la personne le veut sans la musique, comme ses propres bobines SFX propres. Faites une version sans musique (from_cues.py ... --ui library --drop-original, puisbed.py --id ... --level -46avec une ambiance favorite), et une version avec musique si utile, et dites laquelle est laquelle. Dans un choix aveugle de trois (original / effets sur musique / effets seuls) la personne a choisi la dernière sans une seule plainte.from_cuesimprimeBAKED:sur un tel film bien qu'il n'y ait pas de synthèse intégrée (parole 0 %, musique 84 %, les attaques ne correspondent pas aux événements : 7 % contre 9 % par hasard) : c'est une fausse alerte. - Synthèse intégrée dans la piste (le projet a été écrit pour une partition synthétisée) : les vrais sons par-dessus créent un doublon.
from_cues.pyle vérifie lui-même (BAKED:,unbake:) et supprime la synthèse de la base sans toucher à la musique et à la voix ; comment exactement, et que faire si le script échoue ou si la synthèse se trouve dans la piste musicale (--extra-synth) :references/project-audio.md(lisez-le dès que la sortie aBAKED,WARN stems,unbake: not possible, ou que le projet synthétise son son avec un script). Après la construction,critique.pyimprime l'axedoubling: la corrélation de la couche avec l'original et avec le nouveau film (devrait être d'environ 0). - Le son des clips joués dans une fenêtre d'enregistrement d'écran : natif, reste ; les événements à l'intérieur de ces fenêtres sont ignorés.
2. Trouver les moments (de la meilleure source à la pire)
- La liste d'événements du projet ou le script du synthétiseur →
from_cues.py(ci-dessous). En détail :references/typed-cues.md. - Un enregistrement d'écran →
references/screencast.md(ui_events.pyrégions, correspondance des frappes avec les caractères, son du clip). - HyperFrames avec
data-startet sans liste :from_hyperframes.py PROJECT --out work/moments.json. "1 moments" avec 18 éléments signifie que le mouvement ne suit pasdata-start: cherchez un script de synthétiseur. - Vidéo uniquement :
find_moments.py FILM --out work/moments [--roi x,y,w,h] [--from A --to B] [--fine]; typescut,burst,onset,settle(settlese déclenche aussi sur une image vide ou une boucle au repos : regardez l'image) ;look.py --moments ...dessine les images des moments. Squelette :suggest_cues.py(references/recipes.md) ; une ébauche est un début, pas une réponse.--finepour l'animation douce colorée (dégradés, lueurs, formes pastel qui changent de couleur plutôt que de luminosité) : il lit aussi les changements de chrominance, les moments ontsrc=chroma|luma; sur trois tels films, il trouve 33 à 69 % des événements qu'un agent a notés à partir des images (à moins de 80 ms), contre 13 à 25 % avec la seule luminosité ; 3 à 4 fois plus de candidats (15 à 25 par 10 s). Ce sont des candidats : les images décident. - Sous la musique :
beats.py FILM --out work/beats.json --plot work/beats.png; avecusable: true,mix.py --snap-beats(±50 ms). La grille est vérifiée par rapport à la grosse caisse (la bande basse < 125 Hz séparément) : elle imprime combien de battements ont atterri sur une grosse caisse en moins de 40 ms. Une grille à côté de la grosse caisse (le tracker s'est posé sur les charlestons, "0,22 s de décalage") est déplacée dessus ; une grille qui n'atterrit sur rien reçoitusable: false, et--snap-beatsl'ignore.--plotdessine la bande, les grosses caisses (marques vertes) et la grille (lignes rouges) : les marques sont sur les lignes, ou ne faites pas confiance à la grille. Si la musique est à vous et peut être adaptée à l'image :beats.py FILM --suggest-offset work/moments.jsondit de combien décaler la musique pour que les coupures et les impacts atterrissent sur les battements (conseil uniquement ; la musique n'est pas touchée).
from_cues.py : python scripts/from_cues.py LIST|PROJECT_FOLDER|SCRIPT.cjs|- --video RENDER.mp4 --out work/cues.json (- lit la liste depuis l'entrée standard ; un BOM de PowerShell est compris). Ce qu'il fait et dit par lui-même :
- est-ce le bon rendu : la liste manque l'image (
VERDICT) ; une liste en phase de conception contre un rendu chronométré par rapport à la voix : une carte temporelle à partir des ancres du projet (timing.jsonaveca...
[...tronqué pour la traduction]