Communitygithub.com

zenstory-ai/video-reference

Décomposer un film fini en références de production réutilisables : mesurer le rythme des plans et la sonie, annoter les segments et la répartition des pistes audio, séparer les faits originaux des méthodes transférables, et exporter un fichier production_reference.json sans noms propres ni dialogues de la vidéo source, pour référence lors de la prochaine production.

Qu'est-ce que video-reference ?

Cette compétence permet de décomposer une vidéo de commentaire narratif déjà montée afin d'en extraire des métriques objectives et des méthodes de montage réutilisables, le tout en local. Elle mesure les coupes de plans, la sonie (LUFS, LRA), détecte les rythmes et calcule la densité de coupes, puis assiste l'humain pour valider les coupes, annoter les pistes audio et les segments narratifs. Les faits propres à la vidéo source (noms, dialogues, scénario) sont séparés des méthodes génériques, et le livrable final, `production_reference.json`, est expurgé de toute information confidentielle. Fonctionne avec ffmpeg et des scripts Python ; ne nécessite aucun appel à un LLM. Prise en charge de Claude Code, Cursor, Codex et tout agent capable d'exécuter des commandes locales.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/zenstory-ai/video-recap-skills/tree/HEAD/skills/video-reference

Demander à votre IA préférée

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

Documentation

1. Positionnement

Cette compétence permet de décomposer, à la demande, une vidéo de commentaire narratif déjà montée pour en extraire le rythme de montage, la répartition sonore et les techniques narratives sous forme de fiches méthodes et d'indicateurs quantitatifs directement utilisables pour la prochaine production. Tout s'exécute en local, ne produit que des données de mesure, des annotations de décomposition et un fichier de référence expurgé ; aucun appel à MiMo ni notation ou blocage sur la chaîne de production courante.

L'Agent joue ici le rôle de monteur-analyseur : il note d'abord les faits objectifs de la vidéo source (comment elle est montée, mixée) puis en extrait des méthodes transférables à un nouveau contenu. Les faits et les méthodes doivent être strictement séparés : les faits contenant des noms, de l'intrigue et des dialogues de la vidéo source restent uniquement dans le répertoire de décomposition local ; le fichier production_reference.json final ne contient que les méthodes génériques et les valeurs rythmiques mesurées.

2. Entrées

  • Fichier vidéo de la vidéo source à décomposer (formats supportés : .mp4 / .mov / .mkv / .webm).
  • Répertoire U des sorties de compréhension vidéo pour cette vidéo (recommandé : définir ASR_SEGMENT_SECONDS=5 lors de l'étape de compréhension ; plus la fenêtre est fine, plus le débit de la narration est précis). La compétence lira depuis ce répertoire les fichiers optionnels asr_result.json, asr_timing_evidence.json et background_research.json (les noms de personnages, alias et dialogues ASR qui y sont enregistrés seront inclus dans le scan anti-fuite). Pour les annotations manuelles, l'Agent doit également consulter le storyboard et le fichier vlm_analysis.json.

Même sans avoir exécuté la compréhension vidéo, cette compétence peut fonctionner de manière autonome ; les champs de débit de narration seront alors vides, le vocabulaire anti-fuite ne reposera que sur les entities écrites manuellement par l'Agent, et la vérification (check) émettra un avertissement correspondant. Dans ce cas, on peut utiliser frames --span 0,<durée> --step 2 pour extraire des images et générer un storyboard d'aide à la visualisation.

Les chemins scripts/... ci-dessous sont relatifs au répertoire de cette compétence.

3. Processus de décomposition

python3 scripts/reference.py measure <vidéo_source> --work-dir U        # Mesures ffmpeg des coupes et de la sonie, mise en cache par identité de fichier
python3 scripts/reference.py frames  <vidéo_source> --work-dir U --review          # Génère des images pour chaque fenêtre de coupe suspecte afin de les vérifier manuellement
python3 scripts/reference.py frames  <vidéo_source> --work-dir U --longest 5       # Extrait 12 images uniformément réparties des 5 plans les plus longs, pour vérifier les coupes manquées
python3 scripts/reference.py check   --work-dir U [--json]      # Valide le fichier de décomposition et affiche les indicateurs dérivés
python3 scripts/reference.py export  --work-dir U --out <work_dir_de_la_prochaine_production>/production_reference.json
  1. Mesure des plans et de la sonie (measure) : le script génère U/reference_measurements.json (ne pas modifier manuellement), contenant : les points de coupe, la distribution des durées de plans, le nombre de coupes par minute, la courbe de densité de coupes sur une fenêtre glissante de 10 secondes, la sonie intégrée (LUFS), la plage dynamique (LRA), le vrai pic et la sonie instantanée par seconde. Cette étape nécessite un décodage complet de la vidéo (vidéo 720p de 5 minutes : environ 15–70 secondes ; vidéo 4K : environ 7 minutes). Tant que le fichier vidéo n'a pas changé, le cache est réutilisé ; ajuster les seuils --soft-score ou --hard-score ne nécessite pas de nouveau décodage.
    • Logique de détection initiale des coupes : les images avec un score de détection de changement de plan (scdet) ≥10 sont directement considérées comme des coupes ; pour les scores entre 4 et 10, une image n'est considérée comme coupe que si son score est au moins le double du score maximal des autres images non adjacentes dans une fenêtre de ±0.3 seconde autour d'elle (pic local nettement dominant). Cela permet de filtrer la plupart des mouvements de caméra tremblants, des zooms brusques et des flashs ; ces images incertaines sont regroupées dans shots.review_windows. De plus, comme le score scdet soustrait la variation d'image de l'image précédente, un cut dur après un mouvement violent vers une image statique peut donner un score scdet aussi bas que 1 ; l'outil inclut donc également les pics de différence d'image (mafd) dans shots.review_windows pour vérification humaine, sans les considérer comme des coupes automatiques.
  2. Vérification visuelle des coupes (frames) : Aucun seuil fixe n'est fiable sur des vidéos réelles (un cut dur dans une scène de nuit sombre peut n'obtenir qu'un score de 5–7, alors qu'un plan long de combat peut avoir des pics de 7–8 toutes les 0.2 secondes). Une vérification visuelle est donc indispensable. Exécutez frames --review pour générer une image composite de chaque fenêtre de vérification, et frames --longest 5 pour générer une image composite de 12 images uniformément réparties dans les 5 plans les plus longs de la vidéo. Les images sont stockées dans U/reference_frames/ ; le terminal affiche les secondes correspondant à chaque vignette. Après inspection, indiquez les corrections dans labels.cut_fixes : add pour les vraies coupes manquées par l'algorithme (en secondes), remove pour les fausses coupes signalées par erreur (doivent correspondre à une coupe détectée avec une tolérance de ±0.1 seconde). Si tout est correct et qu'aucun ajout/suppression n'est nécessaire, écrivez explicitement "cut_fixes": {} pour indiquer que la vérification a été effectuée. Important : si vous relancez measure et que les fenêtres de vérification changent, les anciennes cut_fixes ne sont plus valides ; l'Agent doit les mettre à jour en fonction des nouvelles fenêtres. Une fois la vérification terminée, toutes les statistiques de plans, les densités de coupes par section et le fichier d'export seront recalculés avec les coupes corrigées.
  3. Annotation des pistes audio et des sections (labels) : l'Agent renseigne labels dans U/reference_breakdown.json : audio_spans (répartition des pistes audio), sections (segments fonctionnels de la narration), subtitles (format des sous-titres) et basis (justification des annotations).
    • Les limites des pistes audio doivent correspondre aux véritables instants de début et de fin du son : les points de transition d'audio_spans doivent se situer au moment où l'oreille entend réellement une voix s'ouvrir ou se fermer, et non au moment où les sous-titres apparaissent ou disparaissent (le point de fin de narration marqué par le début de la vignette de sous-titres est souvent en retard de 0.24–0.42 seconde par rapport à la fin réelle du son). Si le répertoire contient U/speech_boundary_anchors.json, utilisez directement les acoustic_pauses (le start correspond à la fin de la phrase précédente, le end au début de la phrase suivante) pour aligner les limites. En effet, le rapport de changement main/plan (switch_on_cut_share) ne tolère qu'une erreur de ±0.25 seconde autour de la coupe ; si les limites sont mal définies, le taux de changement calculé sera gravement faussé. Les voix off ou monologues intérieurs des personnages de la vidéo source restent dans la piste audio source et sont étiquetés original_dialogue ; si nécessaire, distinguez les dans source_facts et methods.
    • Après avoir rempli labels, exécutez une première fois check pour consulter les valeurs dérivées affichées dans le terminal (derived : durée relative de chaque piste audio, densité de coupes par section, vitesse de parole, proportion de changements audio coïncidant avec des cutures d'image dures, distribution relative des sections fonctionnelles sur l'axe temporel structure, et position relative de la première apparition originale first_original_at).
  4. Extraction des faits et des méthodes transférables (source_facts et methods) : à partir des données objectives calculées, continuez à remplir le même fichier reference_breakdown.json avec les faits de la vidéo source (source_facts, qui doivent être ancrés à des intervalles de temps ou à des chemins de mesure spécifiques, et lister explicitement les noms propres entities) et les méthodes transférables (methods, comprenant la règle rule, les conditions d'application applies_when, les conditions à éviter avoid_when, les fichiers aval concernés applies_to, les preuves evidence et les indicateurs de référence quantifiés targets). Attention : dans targets, seules les références {"from": "<chemin_de_mesure>"} sont autorisées ; il est strictement interdit d'écrire des valeurs numériques explicites dans le texte des règles. Lors de l'export, le script remplit automatiquement les valeurs mesurées.
  5. Validation et export (check → export) : exécutez check pour confirmer l'absence d'erreur, puis export pour générer production_reference.json ; avant d'écrire le fichier, l'exportateur effectue un scan anti-fuite complet sur tous les champs.

La définition complète des champs, les listes d'énumération et les exemples de bonnes/mauvaises méthodes sont disponibles dans references/reference-schema.md.

4. Règles de validation et anti-fuite

reference.py check bloque avec un code de sortie 1 en cas d'erreur suivante :

RègleExigence de validation
R1Les clés de niveau supérieur, labels, fact, method, target, cut_fixes doivent utiliser un ensemble de clés strictement fermé et une énumération fermée ; fact ne doit pas contenir de champs de méthode, method ne doit pas contenir de champs de fait ; les identifiants doivent être de la forme f1… / m1… et uniques globalement ; le type du champ subtitles est fixe ; la raison de skipped_dimensions doit être une chaîne non vide
R2audio_spans et sections doivent être triés par ordre croissant, sans chevauchement, avec un écart entre segments ≤0.5 seconde, et couvrir la totalité de la durée de la vidéo ; les points temporels de capture des sous-titres doivent se situer dans la durée de la vidéo ; cut_fixes.remove doit correspondre à une coupe détectée, add ne doit pas être en double avec une coupe existante
R3Chaque fact doit avoir une ancre temporelle t: [a, b] (dans la durée de la vidéo) ou une ancre de mesure measure: [chemin] (résolvant une valeur non-chaîne sous shots / loudness / derived), et doit explicitement renseigner le tableau entities
R4Chaque method doit lier au moins une preuve : référence à un ID fact défini, ou measure:<chemin> (uniquement sous les trois chemins racines mentionnés)
R5target ne doit contenir que la clé from, pointant vers un nœud feuille numérique sous shots, loudness ou derived, ou un objet dérivé sur liste blanche (voir schema) ; les indices de liste sont interdits
R6Dans rule, applies_when, avoid_when et la raison de skipped_dimensions : interdiction de tout nom propre de la vidéo source (comparaison insensible aux espaces), de toute chaîne de 8 caractères chinois consécutifs identique aux dialogues ASR, données de contexte ou source_facts (interception même à travers la ponctuation ou les fenêtres ASR adjacentes), de toute séquence de 5 mots anglais consécutifs identiques, de tout code temporel absolu, de toute mention de « N-ième seconde » ou « N minutes M secondes » (y compris en chiffres chinois), et de tout chemin absolu local
R7Au moins une method doit être extraite pour chacune des cinq dimensions de production (narrative_structure, pacing, shots_editing, narration_subtitles, audio_visual) ; si une dimension ne peut effectivement pas être extraite, elle doit être justifiée dans skipped_dimensions
R8Lors de l'export du production_reference.json, toutes les clés et valeurs de chaîne sont soumises à un scan anti-fuite R6 ; de plus, les clés source_facts, labels, entities, evidence, statement, from, path sont strictement interdites à tous les niveaux de l'objet exporté

Le vocabulaire anti-fuite est automatiquement constitué des source_facts[].entities, des alias de personnages et character_details dans background_research.json, des entrées cultural_notes de moins de 5 caractères, et des mots courts entre guillemets «」. Si une correspondance de 8 caractères consécutifs avec source_facts est signalée, reformulez simplement la description générique de montage d'un côté.

Les situations suivantes génèrent uniquement un avertissement (warning) sans bloquer l'export : method sans applies_when, présence de chiffres arabes dans rule, précision ASR n'étant pas AVAILABLE_COARSE, vidéo contenant des dialogues en chinois sans noms de personnes dans les résultats de compréhension ni la base de données (seulement les entities écrites manuellement), basis vide, incohérence entre l'identité du fichier vidéo dans les résultats de compréhension et le fichier vidéo mesuré, fenêtres de vérification de coupe non validées (cut_fixes manquant).

Note : R6 ne bloque que les correspondances textuelles, pas les paraphrases qui répètent l'intrigue de la vidéo source avec des mots différents. Lors de la rédaction des methods, vous devez résumer « comment traiter une situation en fonction de la caractéristique du matériel », jamais « comment monter après que le protagoniste soit entré ». De plus, le validateur ne vérifie pas la cohérence sémantique du langage naturel avec les données – avant d'écrire « quel type de segment a des coupes plus denses », vous devez vérifier les valeurs cuts_per_min imprimées par check, et ne jamais tirer de conclusions contraires aux données mesurées.

5. Livrable et utilisation ultérieure

Le fichier production_reference.json exporté contient : la durée totale de la vidéo et ses dimensions, cut_detection (paramètres de détection des coupes et nombre de coupes ajoutées/supprimées manuellement), profile (indicateurs clés de rythme et de sonie, avec marque de provenance provenance : measured pour une mesure purement algorithmique, reviewed pour une validation visuelle via cut_fixes, labeled pour une annotation manuelle des pistes audio/sections), la distribution relative des segments fonctionnels sur l'axe temporel structure, les caractéristiques de format des sous-titres subtitles, la liste des méthodes transférables methods et la justification des dimensions sautées skipped_dimensions.

Utilisation : placez le fichier production_reference.json exporté dans le work_dir de la prochaine tâche de production (ou liez-le via le modèle production_reference du référentiel de ressources). Lors de l'étape de rédaction en aval, si ce fichier est détecté, il est automatiquement lu et chaque méthode est enregistrée avec sa décision d'adoption (adopt / adapt / skip) dans le champ optionnel reference_methods du fichier recap_story_plan.json. Lorsque vous vous référez à ces méthodes, basez-vous toujours sur les images réelles et les dialogues du nouveau matériel ; ne considérez jamais la densité de coupes ou la proportion de silence de la vidéo de référence comme des quotas rigides à appliquer mécaniquement. Aucun script de production ne valide mécaniquement ce fichier ; sa présence ou son absence ne modifie pas le résultat de validation des portes de contrôle.

Le répertoire U/ contient les fichiers reference_breakdown.json et les images composites reference_frames/ qui incluent les faits et les images de la vidéo source. Ils sont destinés uniquement à la décomposition locale sur cette machine ; ne les copiez pas dans un nouveau projet et ne les soumettez pas à un dépôt public.

6. Périmètre fonctionnel

  • Calculs entièrement locaux, sans appel à MiMo ni à aucun grand modèle de langage, sans modification des sorties de compréhension vidéo en amont, et sans évaluation de la qualité de la vidéo source ni calcul d'écart avec un nouveau contenu.
  • La détection des coupes est basée sur le score scdet de ffmpeg avec une validation visuelle humaine : les transitions par fondu enchaîné lent ne peuvent pas être détectées automatiquement ; deux coupes rapides consécutives espacées de moins de 0.3 seconde, les coupes juste à la limite du seuil soft_score (où différentes versions de ffmpeg peuvent donner 4.00 ou 3.989), et les coupes dures après un mouvement violent vers un champ sombre (score pouvant descendre à 0.9) ne sont pas considérées comme des coupes automatiques, mais sont regroupées dans les fenêtres de vérification pour validation humaine. Lors d'un test sur un commentaire de 5 minutes d'une série, la détection initiale a trouvé 82 coupes, et parmi les 11 fenêtres de vérification, les 5 vraies coupes manquées ont été identifiées (les 7 autres fenêtres étaient des zooms rapides, des pages tournées et des mouvements de caméra) ; après ajout manuel de ces 5 coupes, la correspondance avec les 27 coupes de référence (validées image par image sur l'introduction, le champ sombre et le milieu) était de 100 % sans fausse alerte.
  • La proportion de narration et le débit de parole sont de niveau labeled : estimés à partir des plages audio annotées manuellement et des fenêtres ASR grossières, sans alignement temporel mot à mot.
  • Le scan anti-fuite est basé sur une comparaison textuelle littérale ; l'Agent doit toujours vérifier lui-même que les methods décrivent des techniques de création génériques et non le résumé de l'histoire de la vidéo source.

Individual skills in this repo

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

Skills associés