madoo.video-scenes/v1
Madoo video scenes — What a video is made of: its scenes between cuts and black gaps, the gaps, and the frames chosen for each scene (Extract Scenes).
| Reference | madoo.video-scenes/v1 |
| Schema id | urn:madoo:schema:video-scenes:v1 |
| Version | 1.0.0 |
| Served at | GET /api/v1/json-schemas/madoo.video-scenes/v1 · MCP get_json_schema |
Where it appears
Section titled “Where it appears”- Produced by:
video/extract_scenes→scenes
Fields
Section titled “Fields”| Field | Type | Required | Rules | Description |
|---|---|---|---|---|
schema |
"madoo.video-scenes/v1" |
yes | ||
video |
object | yes | ||
video.duration |
number | yes | ≥ 0 | Seconds. |
video.width |
integer | ≥ 1 | As displayed (a phone video rotated by 90° shows its height as width). | |
video.height |
integer | ≥ 1 | ||
video.frame_rate |
number | ≥ 0 | ||
settings |
object | yes | ||
settings.mode |
one of "scenes", "interval", "scenes_and_interval" |
yes | ||
settings.threshold |
number | yes | ≥ 0; ≤ 1 | |
settings.subtle_cuts |
boolean | yes | ||
settings.black_gap_seconds |
number | yes | ≥ 0 | |
settings.min_scene_seconds |
number | yes | ≥ 0 | |
settings.interval_seconds |
number | yes | > 0 | |
settings.max_frames |
integer | yes | ≥ 1 | |
scenes |
array of objects | yes | ||
scenes[].index |
integer | yes | ≥ 1 | |
scenes[].start |
number | yes | ≥ 0 | |
scenes[].end |
number | yes | ≥ 0 | |
scenes[].duration |
number | yes | ≥ 0 | |
scenes[].opened_by |
one of "start", "cut", "gap" |
yes | What begins the scene: the start of the video, a cut, or the end of a black gap. | |
scenes[].cut_score |
number | ≥ 0; ≤ 1 | The change score of the cut that opens the scene. | |
scenes[].subtle |
boolean | True when the cut was found by Subtle Cuts: below the threshold, far above the seconds around it (a jump cut in the same framing). | ||
scenes[].frames |
array of objects | yes | min items 1 | |
scenes[].frames[].time |
number | yes | ≥ 0 | |
scenes[].frames[].frame |
integer | yes | ≥ 1 | Index of the image in the image set. |
scenes[].frames[].dark |
boolean | True when no lit frame was found in its stretch. | ||
gaps |
array of objects | yes | ||
gaps[].start |
number | yes | ≥ 0 | |
gaps[].end |
number | yes | ≥ 0 | |
gaps[].kind |
"black" |
yes | ||
reduced |
boolean | yes | True when frames were given up or scenes joined across the weakest cuts to respect max_frames. |
The complete schema
Section titled “The complete schema”madoo.video-scenes/v1 (JSON Schema)
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "urn:madoo:schema:video-scenes:v1", "title": "Madoo video scenes", "description": "What a video is made of, found by Extract Scenes (video/extract_scenes): its scenes — the picture between two cuts or black gaps — the black gaps themselves, and the frames chosen for each scene, pointing into the madoo.image-set/v1 written beside it (frames[].frame = the image's index there). Times in seconds; scenes and gaps together cover the video. A cut is a frame whose change score (0–1) is above the threshold; a gap is a black stretch at least black_gap_seconds long, such as a fade through black; it is no scene. Mode interval does not look for cuts or gaps: one scene covers the video.", "type": "object", "required": [ "schema", "video", "settings", "scenes", "gaps", "reduced" ], "properties": { "schema": { "const": "madoo.video-scenes/v1" }, "video": { "type": "object", "required": [ "duration" ], "properties": { "duration": { "type": "number", "minimum": 0, "description": "Seconds." }, "width": { "type": "integer", "minimum": 1, "description": "As displayed (a phone video rotated by 90° shows its height as width)." }, "height": { "type": "integer", "minimum": 1 }, "frame_rate": { "type": "number", "minimum": 0 } } }, "settings": { "type": "object", "required": [ "mode", "threshold", "subtle_cuts", "black_gap_seconds", "min_scene_seconds", "interval_seconds", "max_frames" ], "properties": { "mode": { "enum": [ "scenes", "interval", "scenes_and_interval" ] }, "threshold": { "type": "number", "minimum": 0, "maximum": 1 }, "subtle_cuts": { "type": "boolean" }, "black_gap_seconds": { "type": "number", "minimum": 0 }, "min_scene_seconds": { "type": "number", "minimum": 0 }, "interval_seconds": { "type": "number", "exclusiveMinimum": 0 }, "max_frames": { "type": "integer", "minimum": 1 } } }, "scenes": { "type": "array", "items": { "type": "object", "required": [ "index", "start", "end", "duration", "opened_by", "frames" ], "properties": { "index": { "type": "integer", "minimum": 1 }, "start": { "type": "number", "minimum": 0 }, "end": { "type": "number", "minimum": 0 }, "duration": { "type": "number", "minimum": 0 }, "opened_by": { "enum": [ "start", "cut", "gap" ], "description": "What begins the scene: the start of the video, a cut, or the end of a black gap." }, "cut_score": { "type": "number", "minimum": 0, "maximum": 1, "description": "The change score of the cut that opens the scene." }, "subtle": { "type": "boolean", "description": "True when the cut was found by Subtle Cuts: below the threshold, far above the seconds around it (a jump cut in the same framing)." }, "frames": { "type": "array", "minItems": 1, "items": { "type": "object", "required": [ "time", "frame" ], "properties": { "time": { "type": "number", "minimum": 0 }, "frame": { "type": "integer", "minimum": 1, "description": "Index of the image in the image set." }, "dark": { "type": "boolean", "description": "True when no lit frame was found in its stretch." } } } } } } }, "gaps": { "type": "array", "items": { "type": "object", "required": [ "start", "end", "kind" ], "properties": { "start": { "type": "number", "minimum": 0 }, "end": { "type": "number", "minimum": 0 }, "kind": { "const": "black" } } } }, "reduced": { "type": "boolean", "description": "True when frames were given up or scenes joined across the weakest cuts to respect max_frames." } }, "examples": [ { "schema": "madoo.video-scenes/v1", "video": { "duration": 40, "width": 640, "height": 360, "frame_rate": 30 }, "settings": { "mode": "scenes", "threshold": 0.3, "subtle_cuts": false, "black_gap_seconds": 0.3, "min_scene_seconds": 1, "interval_seconds": 10, "max_frames": 100 }, "scenes": [ { "index": 1, "start": 0, "end": 5.267, "duration": 5.267, "opened_by": "start", "frames": [ { "time": 2.633, "frame": 1 } ] }, { "index": 2, "start": 6.267, "end": 16.333, "duration": 10.067, "opened_by": "gap", "frames": [ { "time": 11.3, "frame": 2 } ] } ], "gaps": [ { "start": 5.267, "end": 6.267, "kind": "black" } ], "reduced": false } ]}