Takes a video by URL or inline base64 and reports where the picture changes
Takes a video by URL or inline base64 and reports where the picture changes. FFmpeg measures the difference between consecutive frames; every jump above the threshold starts a new scene, and the answer lists each scene with start, end, duration and the fraction of the running time it covers, plus the raw detection score positions.
Answeringour last check, 2026-09-24
1 of 1checks answered this week
1158 msmedian answer time
$0.03listed price per call
$0.03price it asked us
Paid test badge: not yet. The checks above are free: we call the tool without paying and read the payment request it sends back. The Verified badge needs paid calls whose answers match the promised output, and nobody can buy a badge.
Endpoint
POST https://medien.halowerk.com/v1/keyframes
| Category | Image and media |
|---|---|
| Provider host | medien.halowerk.com |
| Networks | eip155:8453 |
| Payment schemes | exact |
| Self-reported calls, 30 days | 2 from 1 payers (the provider's figure, not ours) |
Our checks, last 30 days
| Day | Result | HTTP | Asked | Time |
|---|---|---|---|---|
| 2026-09-24 | valid payment request | 402 | $0.03 | 1158 ms |
Example input (from the provider)
{
"body": {
"duration_minutes": 3,
"include_thumbnails": true,
"scene_threshold": 0.35,
"source": {
"url": "https://example.com/film.mp4"
}
},
"bodyType": "json",
"method": "POST",
"type": "http"
}
Promised output schema (from the provider)
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"input": {
"additionalProperties": false,
"properties": {
"body": {
"additionalProperties": false,
"properties": {
"duration_minutes": {
"default": 1,
"description": "Length of the video in started minutes \u2014 this is what you are billed for. A longer video is refused with its real duration and nothing is charged; a shorter one simply costs what you declared, and the answer says how much less it would have been.",
"maximum": 30,
"minimum": 1,
"type": "integer"
},
"include_thumbnails": {
"default": false,
"description": "Render one JPEG per scene and return it base64.",
"type": "boolean"
},
"max_scenes": {
"default": 100,
"description": "Ceiling on returned scenes. What is dropped is counted and reported.",
"maximum": 400,
"minimum": 1,
"type": "integer"
},
"max_thumbnails": {
"default": 20,
"description": "Ceiling on rendered thumbnails, independent of the scene count.",
"maximum": 60,
"minimum": 1,
"type": "integer"
},
"min_scene_seconds": {
"default": 0.4,
"description": "Merge cuts closer together than this. Guards against flicker being read as a cut.",
"maximum": 60,
"minimum": 0,
"type": "number"
},
"scene_threshold": {
"default": 0.35,
"description": "Frame-to-frame difference above which a new scene starts. Lower finds more, higher finds fewer.",
"maximum": 0.95,
"minimum": 0.05,
"type": "number"
},
"source": {
"additionalProperties": false,
"description": "The video. Either url or content_base64.",
"properties": {
"content_base64": {
"description": "The video inline, base64. Larger files must come by url.",
"maxLength": 12000000,
"type": "string"
},
"filename": {
"maxLength": 260,
"type": "string"
},
"url": {
"description": "Public http(s) URL of the video.",
"maxLength": 2048,
"type": "string"
}
},
"type": "object"
},
"thumbnail_width": {
"default": 160,
"description": "Width of the thumbnails; height follows the aspect ratio.",
"maximum": 640,
"minimum": 32,
"type": "integer"
}
},
"required": [
"source"
],
"type": "object"
},
"bodyType": {
"enum": [
"json",
"form-data",
"text"
],
"type": "string"
},
"method": {
"enum": [
"POST",
"PUT",
"PATCH"
],
"type": "string"
},
"type": {
"const": "http",
"type": "string"
}
},
"required": [
"type",
"method",
"bodyType",
"body"
],
"type": "object"
}
},
"required": [
"input"
],
"type": "object"
}