Files
DanceVideos/model/video_analysis_extension.sql
CI Bot 5f0311ffa5 model : ajoute beat_atoms (V0.10 atomes — voir video_analysis/adr/0018)
Table pour les atomes de mouvement par-beat (1 enregistrement par beat × danseur).
Modèle hybride à 3 niveaux : continu (foot_height/speed/stability) + soft
distribution (state_dist_json sommant à 1 sur planted/touch/lifted/transitioning)
+ argmax (state + confidence).

Implémenté dans pipeline/atoms.py côté video_analysis (commit 654320a).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 01:24:05 +02:00

291 lines
14 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- Extension du schéma DanceVideos/ pour le projet video_analysis/
-- Voir adr/0004-db-extension-strategy.md
-- Convention héritée de DanceVideos : la PK de `videos` est `file_name VARCHAR(255)`,
-- les tables filles utilisent `video_file_name VARCHAR(255)` comme FK.
PRAGMA foreign_keys = ON;
-- Groupes de vidéos d'un même cours (V0.6, voir adr/0010)
CREATE TABLE IF NOT EXISTS video_groups (
id INTEGER PRIMARY KEY AUTOINCREMENT,
label TEXT,
time_start DATETIME,
time_end DATETIME,
n_videos INTEGER,
style TEXT,
pipeline_version TEXT NOT NULL,
notes TEXT
);
CREATE TABLE IF NOT EXISTS video_group_members (
video_file_name VARCHAR(255) PRIMARY KEY,
group_id INTEGER NOT NULL,
role TEXT CHECK (role IN ('explicative', 'demonstration', 'mixte', 'unknown')),
seq_idx INTEGER,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE,
FOREIGN KEY (group_id) REFERENCES video_groups(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_vgm_group ON video_group_members(group_id);
-- Une analyse par version de pipeline et par vidéo
CREATE TABLE IF NOT EXISTS analyses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
niveau TEXT NOT NULL, -- "audio_demix" | "beats" | "asr" | "pose" | "segment" | "label"
pipeline_version TEXT NOT NULL,
started_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
finished_at DATETIME,
summary_json TEXT,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_analyses_video ON analyses(video_file_name, niveau);
-- Segmentation audio (parole / musique / silence / mixed)
CREATE TABLE IF NOT EXISTS audio_segments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
start_s REAL NOT NULL,
end_s REAL NOT NULL,
kind TEXT NOT NULL CHECK (kind IN ('parole', 'musique', 'silence', 'mixed')),
speaker_id TEXT,
text TEXT,
confidence REAL,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_audio_segments_video ON audio_segments(video_file_name, start_s);
-- Beats / downbeats / tempo
CREATE TABLE IF NOT EXISTS beats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
t_s REAL NOT NULL,
beat_in_bar INTEGER NOT NULL, -- 1..4 typiquement
is_downbeat BOOLEAN NOT NULL,
bpm REAL,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_beats_video ON beats(video_file_name, t_s);
-- Régimes intra-vidéo (avec_compte / en_musique / mixte / explication / silence) — voir adr/0009
CREATE TABLE IF NOT EXISTS regime_segments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
start_s REAL NOT NULL,
end_s REAL NOT NULL,
regime TEXT NOT NULL CHECK (regime IN ('avec_compte', 'en_musique', 'mixte', 'explication', 'compte_avec_explication', 'silence')),
confidence REAL,
pipeline_version TEXT NOT NULL,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_regime_video_t ON regime_segments(video_file_name, start_s);
-- Transcription word-level (WhisperX) — voir adr/0008
CREATE TABLE IF NOT EXISTS transcription_words (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
audio_segment_id INTEGER,
t_start_s REAL NOT NULL,
t_end_s REAL NOT NULL,
word TEXT NOT NULL,
speaker_id TEXT,
confidence REAL,
pipeline_version TEXT NOT NULL,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE,
FOREIGN KEY (audio_segment_id) REFERENCES audio_segments(id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_words_video_t ON transcription_words(video_file_name, t_start_s);
CREATE INDEX IF NOT EXISTS idx_words_text ON transcription_words(word);
-- Labels sémantiques attachés aux dance_segments depuis l'ASR (V0.5.4)
CREATE TABLE IF NOT EXISTS dance_segment_labels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
segment_id TEXT NOT NULL,
label TEXT NOT NULL,
category TEXT, -- "body_part" | "movement" | "direction" | "figure" | "rhythm"
source TEXT NOT NULL CHECK (source IN ('asr-keyword', 'asr-figure', 'user', 'manual')),
t_offset_s REAL, -- décalage du keyword par rapport au début du segment (négatif = avant)
confidence REAL,
pipeline_version TEXT NOT NULL,
FOREIGN KEY (segment_id) REFERENCES dance_segments(segment_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_dsl_segment ON dance_segment_labels(segment_id);
CREATE INDEX IF NOT EXISTS idx_dsl_label ON dance_segment_labels(label);
-- Personnes détectées dans la vidéo (prof, partenaire, audience)
CREATE TABLE IF NOT EXISTS persons (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
person_id INTEGER NOT NULL, -- ID stable inter-frames (ByteTrack)
role TEXT NOT NULL CHECK (role IN ('prof', 'partner', 'audience', 'unknown')),
notes TEXT,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE,
UNIQUE (video_file_name, person_id)
);
-- Pose keypoints (frame-decimated, 1/N frame typiquement)
CREATE TABLE IF NOT EXISTS pose_keypoints (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
frame INTEGER NOT NULL,
person_id INTEGER NOT NULL,
kp_json TEXT NOT NULL, -- JSON compressé : 133 keypoints {x, y, score}
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_pose_kp_video_frame ON pose_keypoints(video_file_name, frame);
-- Segments hiérarchiques de chorégraphie (cœur de l'UX cumulation/réduction)
CREATE TABLE IF NOT EXISTS dance_segments (
segment_id TEXT PRIMARY KEY, -- ex. "v17:meso:0008"
video_file_name VARCHAR(255) NOT NULL,
start_s REAL NOT NULL,
end_s REAL NOT NULL,
level TEXT NOT NULL CHECK (level IN ('macro', 'meso', 'micro', 'nano')),
parent_segment_id TEXT,
label TEXT,
source TEXT NOT NULL CHECK (source IN ('auto-rules', 'auto-tcn', 'teacher-said', 'user')),
confidence REAL,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE,
FOREIGN KEY (parent_segment_id) REFERENCES dance_segments(segment_id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_dance_segments_video ON dance_segments(video_file_name, level, start_s);
CREATE INDEX IF NOT EXISTS idx_dance_segments_parent ON dance_segments(parent_segment_id);
-- Patterns nommés (mise en espagnol, dile que no, pas de bourré...)
CREATE TABLE IF NOT EXISTS patterns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
description TEXT,
style TEXT, -- "salsa cubaine" | "bachata" | "common" | ...
templates_json TEXT, -- liste d'occurrences (video_file_name + segment_id) servant de templates
occurrences_count INTEGER DEFAULT 0
);
-- Benchmarks — résultats d'évaluation par pipeline_version × méthode × tolérance × vidéo
-- (voir doc/observabilite-backoffice.md § 5, notebooks/02-segmentation-eval)
CREATE TABLE IF NOT EXISTS benchmarks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pipeline_version TEXT NOT NULL, -- ex. "v0.5.0", "v0.5.0-beat_this-raw-audio"
run_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
notebook TEXT, -- nom/chemin du notebook qui a produit la mesure
golden_set TEXT, -- ex. "decoupe/diegoRiviera.json" ou "decoupe/all"
video_file_name VARCHAR(255), -- vidéo ; nullable si métrique agrégée
method TEXT NOT NULL, -- "V0_meso" | "4bar_grid" | "uniform_5s" | ...
tol_s REAL NOT NULL, -- tolérance en secondes
precision_score REAL NOT NULL,
recall_score REAL NOT NULL,
f1_score REAL NOT NULL,
n_pred INTEGER NOT NULL,
n_gold INTEGER NOT NULL,
notes TEXT,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_benchmarks_version ON benchmarks(pipeline_version, method, tol_s);
CREATE INDEX IF NOT EXISTS idx_benchmarks_run ON benchmarks(run_at);
-- Journal d'éditions (audit trail + undo/redo unifiés) — voir adr/0013
CREATE TABLE IF NOT EXISTS edits_journal (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL DEFAULT 'default',
video_file_name VARCHAR(255),
transaction_id TEXT NOT NULL,
op_type TEXT NOT NULL,
target_table TEXT NOT NULL,
target_id TEXT NOT NULL,
before_json TEXT,
after_json TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
undone_at DATETIME,
redone_at DATETIME,
pipeline_version TEXT,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_edits_video_t ON edits_journal(video_file_name, created_at);
CREATE INDEX IF NOT EXISTS idx_edits_txn ON edits_journal(transaction_id);
CREATE INDEX IF NOT EXISTS idx_edits_active ON edits_journal(undone_at, created_at);
-- Handles d'ancrage cross-vidéo (paires _C_/_M_) — voir adr/0014
CREATE TABLE IF NOT EXISTS video_group_handles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id INTEGER NOT NULL,
source_video VARCHAR(255) NOT NULL,
source_t_s REAL NOT NULL,
target_video VARCHAR(255) NOT NULL,
target_t_s REAL NOT NULL,
label TEXT,
created_by TEXT NOT NULL DEFAULT 'default',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
notes TEXT,
FOREIGN KEY (group_id) REFERENCES video_groups(id) ON DELETE CASCADE,
FOREIGN KEY (source_video) REFERENCES videos(file_name) ON DELETE CASCADE,
FOREIGN KEY (target_video) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_handle_group ON video_group_handles(group_id);
CREATE INDEX IF NOT EXISTS idx_handle_pair ON video_group_handles(source_video, target_video);
-- Prédictions de style par classifieur RF (V0.6.1, voir adr/0011)
CREATE TABLE IF NOT EXISTS style_predictions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
file_name VARCHAR(255) NOT NULL,
style TEXT NOT NULL,
confidence REAL,
model_version TEXT NOT NULL,
predicted_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_stylepred_file ON style_predictions(file_name);
CREATE INDEX IF NOT EXISTS idx_stylepred_style ON style_predictions(style);
-- État de navigation persistant (UX cumulation/réduction)
CREATE TABLE IF NOT EXISTS nav_state (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
user_id TEXT NOT NULL DEFAULT 'default',
current_segment_id TEXT,
view_level TEXT CHECK (view_level IN ('macro', 'meso', 'micro', 'nano')),
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE,
FOREIGN KEY (current_segment_id) REFERENCES dance_segments(segment_id) ON DELETE SET NULL,
UNIQUE (video_file_name, user_id)
);
-- Atomes de mouvement (V0.10, voir adr/0018) — granularité beat / demi-beat.
-- Modèle hybride : continu + soft distribution + argmax + confidence.
CREATE TABLE IF NOT EXISTS beat_atoms (
id INTEGER PRIMARY KEY AUTOINCREMENT,
video_file_name VARCHAR(255) NOT NULL,
person_id INTEGER NOT NULL DEFAULT 0,
t_s REAL NOT NULL,
beat_position REAL NOT NULL,
is_downbeat BOOLEAN NOT NULL,
-- Pied gauche
left_foot_height REAL,
left_foot_speed REAL,
left_foot_stability REAL,
left_foot_state VARCHAR(20),
left_foot_state_confidence REAL,
left_foot_state_dist_json TEXT,
-- Pied droit
right_foot_height REAL,
right_foot_speed REAL,
right_foot_stability REAL,
right_foot_state VARCHAR(20),
right_foot_state_confidence REAL,
right_foot_state_dist_json TEXT,
-- Transfert de poids
weight_ratio REAL,
weight_transfer_velocity REAL,
weight_on VARCHAR(10),
-- Cinématique bassin (en hip-widths)
pelvis_x REAL,
pelvis_y REAL,
pelvis_vel_x REAL,
pelvis_vel_y REAL,
-- Qualité globale
pose_confidence REAL NOT NULL,
pipeline_version TEXT NOT NULL,
computed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (video_file_name) REFERENCES videos(file_name) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_atom_video_t ON beat_atoms(video_file_name, t_s);
CREATE INDEX IF NOT EXISTS idx_atom_video_beat ON beat_atoms(video_file_name, beat_position);