/docs · CueLab · Deep
Concevoir des données de conduite qui survivent à une réorganisation
Une conduite est d’abord un modèle de données et seulement ensuite une UI. Traitez-la comme tel.
La plupart des logiciels de conduite traitent la liste de cues comme un artefact d’UI : un tableau de type tableur où chaque ligne est un cue, chaque colonne une propriété, et où l’utilisateur saisit du texte dans des cellules. Cela convient jusqu’à ce que vous vouliez réordonner le spectacle, ramifier le script, partager des cues avec un autre opérateur ou migrer vers un autre outil.
Une liste de cues conçue d’abord comme un modèle de données (où l’UI est la projection et non la source de vérité) survit proprement à toutes ces opérations. Voici le schéma qui fonctionne.
Le cue minimal viable
interface Cue {
id: string; // stable, never changes
index: number; // display position; can change
type: CueType; // 'audio' | 'video' | 'lighting' | 'scene' | 'note'
label: string; // human-readable name
description?: string; // longer note for the operator
duration?: number; // seconds, optional
trigger: TriggerSpec; // when to fire
payload: unknown; // type-specific data
}
Cinq champs méritent leur place :
id: un UUID ou une courte chaîne. Stable à travers les renommages, les réordonnancements et les modifications. Les références entre cues utilisent l’id, jamais l’index.index: l’ordre d’affichage. Change constamment. Ne le traitez jamais comme une identité.type: le genre de cue. Utilisé par l’UI pour router vers le bon moteur de rendu.trigger: le moment où le cue se déclenche. Voir ci-dessous.payload: tout ce qui est spécifique au type. Les cues audio portent des chemins de fichiers et des niveaux ; les cues d’éclairage portent des paires canal/valeur.
Les déclencheurs comme type somme
Un cue peut se déclencher sur :
type TriggerSpec =
| { kind: 'manual' } // operator hits GO
| { kind: 'after'; previousId: string; delay: number } // chained
| { kind: 'absolute'; t: number } // at clock time t
| { kind: 'timecode'; t: number } // at SMPTE/MIDI time
| { kind: 'event'; eventName: string }; // external signal
La plupart des applications réduisent tous les déclencheurs à « manual » parce que l’UI ne prend pas en charge le reste. Une fois que vous encodez les déclencheurs comme un véritable type somme, vous pouvez construire des séquences chaînées, des cues verrouillés dans le temps et des cues pilotés par événement sans modifier l’UI pour chacun.
Pourquoi cela compte : le problème de la réorganisation
Le mode de défaillance le plus fréquent dans les outils de conduite est la réorganisation. Vous décidez de déplacer la scène 3 après la scène 5. Dans un outil orienté UI, vous faites glisser la ligne vers le bas. Dans un outil orienté données, vous échangez les index.
Maintenant : qu’en est-il de toutes les références ? Si le cue 17 (« fondre la musique à la fin de la scène 3 ») référence le cue 12 par l’index, votre déplacement vient de le casser. S’il le référence par l’id, le déplacement est sans effet pour la chaîne : le cue 17 se déclenche toujours après le cue 12, quel que soit l’endroit où ils ont fini dans l’ordre d’affichage.
C’est le genre de chose qui vous rattrape 10 minutes avant le lever de rideau. Construire le schéma autour d’ids stables élimine toute une classe d’incidents.
Versionnage
Chaque liste de cues a besoin d’une version. Ajouter un nouveau genre de déclencheur ne devrait pas casser les anciens fichiers ; en retirer un ne devrait pas les corrompre silencieusement. Le modèle pragmatique :
{
"schemaVersion": 2,
"cues": [ ... ],
"metadata": { ... }
}
Et dans votre chargeur :
function loadCueList(json: unknown): CueList {
const v = (json as { schemaVersion?: number }).schemaVersion ?? 1;
if (v === 1) return migrateV1ToV2(json as CueListV1);
if (v === 2) return json as CueListV2;
throw new Error(`Unknown cue list schema version: ${v}`);
}
Les 10 minutes que vous consacrez maintenant à la migration vous épargnent plus tard 10 heures de « on n’arrive pas à ouvrir le fichier du dernier spectacle ».
Ce qui va dans les métadonnées
Des choses qui ne sont pas des cues mais qui comptent pour le spectacle :
- Nom du spectacle, date, opérateur(s)
- ID des périphériques audio par défaut (afin que la liste de cues s’ouvre proprement sur une autre machine)
- Règles globales (p. ex. « tous les cues entrent en fondu sur 200ms sauf indication contraire »)
- Tags / catégories utilisés dans ce spectacle
Gardez les données de niveau payload hors des métadonnées. Si c’est propre à un cue, cela vit dans le cue.
Pourquoi personne ne le fait
La plupart des outils de conduite sont un tableur plus un bouton Go. Ils fonctionnent parce que les spectacles sont essentiellement linéaires, parce que les modes de défaillance sont pilotés par l’opérateur, et parce que la base d’utilisateurs est assez restreinte pour qu’un schéma robuste ne constitue pas un avantage concurrentiel.
La position de CueLab est que tout cela est à l’envers. Le schéma est le produit ; l’UI est la projection. Une fois le modèle de données solide, vous pouvez construire le bouton Go de cinq manières différentes (pour un streamer, pour un producteur de podcast, pour une équipe d’événementiel live) sans réécrire les fondations.
C’est le travail ennuyeux et important qui fait la différence entre un outil que vous utilisez pour un seul spectacle et un que vous utilisez pendant dix ans.
Articles liés
More in CueLab docs
- Intro
Une checklist d'avant-émission réutilisable
La checklist qui tient bon au moment où votre esprit se vide, trente secondes avant de passer en direct.
- Practical
Le routage audio OBS sans surprises
Le routage audio d’OBS est plus puissant que ne le laisse penser son interface par défaut. Voici le modèle mental qui le rend prévisible.