Video Material Search (for Smart Editing)

Search the copyrighted video material library with a single natural-language scene description or keywords, and get back clips ready to drop onto a timeline — including the best-matching in-clip time ranges (segments), a direct media URL, duration, orientation and fps. Returns synchronously, no polling required.

Designed for smart editing / auto-assembly: query material shot-by-shot from a storyboard, then stitch onto the timeline.

Search Endpoint

Basic Info

ItemValue
MethodPOST
Path/task/video_clip_search
Content-Typeapplication/json
AuthAuthorization header (pass the API Key directly)
ResponseSynchronous search results (not an async task)

Request Body

FieldTypeRequiredDefaultDescription
querystringYesScene description (natural language) or keywords
top_kintegerNo10Number of results, max 50
diversitybooleanNofalseDe-duplicate near-identical shots
request_idstringNouuid, echoed back, for idempotency / tracing
filtersobjectNoEditing-oriented filters, see below

filters Fields

FieldTypeDescription
min_durationnumberMinimum clip duration (seconds)
max_durationnumberMaximum clip duration (seconds)
orientationstringlandscape / portrait / square, to match the output canvas
min_widthintegerMinimum resolution width (pixels)
exclude_idsarray<integer>Material ids to exclude (already used in the same cut)

Request Example

curl -X POST https://api.ai-mcn.tv:10000/task/video_clip_search \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "silhouette of a person with a camera on a coastal rock at sunset",
    "top_k": 10,
    "diversity": true,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "filters": {
      "min_duration": 3,
      "orientation": "landscape",
      "min_width": 1920
    }
  }'

Success Response Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "recalled": 84,
    "results": [
      {
        "clip_id": 2693564728807342,
        "score": 0.87,
        "url": "https://cdn.example.com/nmcn/material/video_clip/raw/2693564728807342.mp4?expires=1750086000&sign=Xa1b2C3d4E5f6G7h8I9j0k",
        "cover_url": "https://cdn.example.com/nmcn/material/video_clip/keyframe/2693564728807342/cover.jpg",
        "preview_url": "https://cdn.example.com/nmcn/material/video_clip/preview/2693564728807342.mp4",
        "duration": 12.4,
        "width": 3840,
        "height": 2160,
        "fps": 25,
        "orientation": "landscape",
        "segments": [
          { "start": 2.0, "end": 8.5, "best": 5.2, "score": 0.91 }
        ],
        "matched": { "facets": { "time_of_day": ["dusk"], "scene": ["coast"] } },
        "note": "Dusk by the sea; a person on the rocky shore filming the water."
      }
    ]
  }
}

Response Fields

FieldTypeDescription
recalledintegerTotal recalled (before filtering), for observability
results[].clip_idintegerMaterial id. Note: this is a large integer that may exceed JS Number.MAX_SAFE_INTEGER (2^53) — JavaScript consumers should treat it as a string (e.g. quote the field at the response-text level before parsing), otherwise precision loss can collide ids of different materials
results[].scorenumberRelevance score (after rerank, sorted descending)
results[].urlstringTemporary media URL (mp4, expires in 24h via ?expires=&sign=; re-search for a fresh link after expiry)
results[].cover_urlstringRepresentative cover image (unsigned, never expires)
results[].preview_urlstringLow-res preview proxy (mp4, width ≤640, no audio track; unsigned, never expires). Ideal for list previews and a proxy-editing workflow: rough-cut with the small proxy first, then download the original via url when finalizing
results[].durationnumberDuration (seconds)
results[].width / heightintegerResolution (pixels)
results[].fpsnumberFrame rate
results[].orientationstringCanvas orientation
results[].segmentsarrayIn-clip matching ranges (sorted by score; first = best)
results[].segments[].start / endnumberRange bounds (seconds), ready for the timeline
results[].segments[].bestnumberBest-matching timestamp within the range (seconds)
results[].matched.facetsobjectMatched visual attributes (scene / time-of-day, etc.)
results[].notestringMaterial text description

Error Codes

CodeHTTPDescriptionResolution
400400Malformed request body (body is not a valid JSON object)Check the request body
6502401Authentication failedCheck the API Key in the Authorization header
6401500Upstream search service unavailable, or request parameters rejected by the search layer (e.g. empty query, invalid orientation/filters values)Verify request parameters first; if correct, retry later
6402500Upstream search service timeoutRetry later

Determine success/failure from the code field in the response body, not the HTTP status code (top_k overflow does not error — it is clamped to 50).

Limits

  • top_k is capped at 50 (clamped automatically).
  • This endpoint takes a single query; for multiple shots, call it concurrently (batch input is a future capability).
  • Searches the copyrighted library only; material quality level is not differentiated.
  • The media url expires in 24h; re-search for a fresh link after expiry (cover_url / preview_url are unsigned and never expire).
  • segments are based on keyframes sampled every 1.5s, so localization accuracy is about ±1.5s.