Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .cspell/custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,13 @@ punycode
userinfo
examplecorp
zapatillas
# rich media formats (video / 3D model source types)
glb
gltf
m3u8
mp4
mpd
mpegurl
usdz
vnd
webm
49 changes: 49 additions & 0 deletions docs/specification/catalog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,57 @@ as the first element. Platforms SHOULD treat the first element as featured.

### Media

A single logical media item on a Product or Variant: an image, a video, or a
3D model. `url` identifies the item's primary resource, and its interpretation
depends on `type`. `preview` is a still image the Platform can render before —
or instead of — loading that resource.

`type` is an open string with three well-known values: `image`, `video`, and
`model_3d`. A Platform **MUST** ignore a media item whose `type` it does not
recognize.

When present, `sources` contains the complete set of available renditions or
encodings. A Business that provides `sources` **SHOULD** include a source whose
`url` equals the media item's `url`, unless `url` is an externally hosted
video's watch page rather than a rendition.

For an image, a self-hosted video, or a 3D model, a Platform loads the
renderable or loadable primary resource at `url`. For an externally hosted
video with `embed_url`, `url` identifies the watch page and `embed_url`
identifies third-party active player content. A Platform **MAY** decline to
embed that content under its security, privacy, or presentation policy and use
the watch-page `url` instead. For a thumbnail, a Platform can use `preview.url`
and fall back to `url` for an image, which is directly displayable.

{{ schema_fields('types/media', 'catalog') }}

#### Image

{{ schema_fields('types/media_image', 'catalog') }}

#### Video

A self-hosted video's `url` identifies its directly playable default rendition.
An externally hosted video is distinguished by `embed_url`, which identifies
the third-party active player content; its `url` identifies the watch page, not
a playable rendition.

A Platform that selects a rendition from `sources` **SHOULD** use the `width`
and `height` of that entry rather than those on the media item, unless the
entry omits them.

For an externally hosted video, a Business **SHOULD** provide both
`preview.width` and `preview.height` with a ratio that matches the intended
player, unless it has no suitable preview. A Platform **SHOULD** reserve the
initial player layout using that ratio, unless its presentation policy supplies
another ratio.

{{ schema_fields('types/media_video', 'catalog') }}

#### 3D Model

{{ schema_fields('types/media_model_3d', 'catalog') }}

### Product Option

{{ schema_fields('types/product_option', 'catalog') }}
Expand Down
74 changes: 73 additions & 1 deletion docs/specification/catalog/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,79 @@ Maps to the [Catalog Lookup](lookup.md#get-product-get_product) capability. Retu
{
"type": "image",
"url": "https://cdn.example.com/products/runner-pro-blue.jpg",
"alt_text": "Runner Pro in Blue"
"alt_text": "Runner Pro in Blue",
"width": 1600,
"height": 1600
},
{
"type": "video",
"url": "https://cdn.example.com/products/runner-pro-demo-720p.mp4",
"name": "Runner Pro flex demo",
"alt_text": "Runner Pro shoe flexing to show sole cushioning",
"duration": 24,
"preview": {
"url": "https://cdn.example.com/products/runner-pro-demo-poster.jpg",
"width": 1280,
"height": 720
},
"sources": [
{
"url": "https://cdn.example.com/products/runner-pro-demo-720p.mp4",
"mime_type": "video/mp4",
"format": "mp4",
"width": 1280,
"height": 720,
"filesize": 4200000
},
{
"url": "https://cdn.example.com/products/runner-pro-demo-1080p.mp4",
"mime_type": "video/mp4",
"format": "mp4",
"width": 1920,
"height": 1080,
"filesize": 8480000
},
{
"url": "https://cdn.example.com/products/runner-pro-demo.m3u8",
"mime_type": "application/vnd.apple.mpegurl",
"format": "m3u8"
}
]
},
{
"type": "model_3d",
"url": "https://cdn.example.com/products/runner-pro.glb",
"alt_text": "Runner Pro 3D model",
"preview": {
"url": "https://cdn.example.com/products/runner-pro-3d-thumb.jpg"
},
"sources": [
{
"url": "https://cdn.example.com/products/runner-pro.glb",
"mime_type": "model/gltf-binary",
"format": "glb",
"filesize": 4200000
},
{
"url": "https://cdn.example.com/products/runner-pro.usdz",
"mime_type": "model/vnd.usdz+zip",
"format": "usdz",
"filesize": 5100000
}
]
},
{
"type": "video",
"url": "https://videos.example.com/watch?v=abc123",
"embed_url": "https://videos.example.com/embed/abc123",
"name": "Runner Pro trail review",
"alt_text": "Reviewer running a trail in the Runner Pro",
"duration": 212,
"preview": {
"url": "https://cdn.example.com/products/runner-pro-review-poster.jpg",
"width": 1280,
"height": 720
}
}
],
"options": [
Expand Down
74 changes: 73 additions & 1 deletion docs/specification/catalog/rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,79 @@ on option values and returns variants matching the selection.
{
"type": "image",
"url": "https://cdn.example.com/products/runner-pro-blue.jpg",
"alt_text": "Runner Pro in Blue"
"alt_text": "Runner Pro in Blue",
"width": 1600,
"height": 1600
},
{
"type": "video",
"url": "https://cdn.example.com/products/runner-pro-demo-720p.mp4",
"name": "Runner Pro flex demo",
"alt_text": "Runner Pro shoe flexing to show sole cushioning",
"duration": 24,
"preview": {
"url": "https://cdn.example.com/products/runner-pro-demo-poster.jpg",
"width": 1280,
"height": 720
},
"sources": [
{
"url": "https://cdn.example.com/products/runner-pro-demo-720p.mp4",
"mime_type": "video/mp4",
"format": "mp4",
"width": 1280,
"height": 720,
"filesize": 4200000
},
{
"url": "https://cdn.example.com/products/runner-pro-demo-1080p.mp4",
"mime_type": "video/mp4",
"format": "mp4",
"width": 1920,
"height": 1080,
"filesize": 8480000
},
{
"url": "https://cdn.example.com/products/runner-pro-demo.m3u8",
"mime_type": "application/vnd.apple.mpegurl",
"format": "m3u8"
}
]
},
{
"type": "model_3d",
"url": "https://cdn.example.com/products/runner-pro.glb",
"alt_text": "Runner Pro 3D model",
"preview": {
"url": "https://cdn.example.com/products/runner-pro-3d-thumb.jpg"
},
"sources": [
{
"url": "https://cdn.example.com/products/runner-pro.glb",
"mime_type": "model/gltf-binary",
"format": "glb",
"filesize": 4200000
},
{
"url": "https://cdn.example.com/products/runner-pro.usdz",
"mime_type": "model/vnd.usdz+zip",
"format": "usdz",
"filesize": 5100000
}
]
},
{
"type": "video",
"url": "https://videos.example.com/watch?v=abc123",
"embed_url": "https://videos.example.com/embed/abc123",
"name": "Runner Pro trail review",
"alt_text": "Reviewer running a trail in the Runner Pro",
"duration": 212,
"preview": {
"url": "https://cdn.example.com/products/runner-pro-review-poster.jpg",
"width": 1280,
"height": 720
}
}
],
"options": [
Expand Down
69 changes: 63 additions & 6 deletions source/schemas/common/types/media.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/common/types/media.json",
"title": "Media",
"description": "Media item (image, video, etc.).",
"description": "A single logical media item: an image, video, or 3D model. `url` is the primary resource; when present, `sources` is the complete set of available renditions. When `sources` is present and `url` identifies a rendition, the Business SHOULD include that rendition.",
"type": "object",
"required": [
"type",
Expand All @@ -11,12 +11,16 @@
"properties": {
"type": {
"type": "string",
"description": "Media type. Well-known values: `image`, `video`, `model_3d`."
"description": "Media type. The Platform MUST ignore unknown values. Well-known values: `image`, `video`, `model_3d`."
},
"url": {
"type": "string",
"format": "uri",
"description": "URL to the media resource."
"description": "Primary/canonical URL for the item; interpretation depends on `type` (specialized per type)."
},
"name": {
"type": "string",
"description": "Human-readable title or label for the media, distinct from `alt_text` (accessibility text). Often present for `video` and `model_3d`."
},
"alt_text": {
"type": "string",
Expand All @@ -25,12 +29,65 @@
"width": {
"type": "integer",
"minimum": 1,
"description": "Width in pixels (for images/video)."
"description": "Pixel width of the media."
},
"height": {
"type": "integer",
"minimum": 1,
"description": "Height in pixels (for images/video)."
"description": "Pixel height of the media."
},
"preview": {
"type": "object",
"description": "Poster/thumbnail still the Platform renders before or instead of the primary resource. A Business SHOULD provide it for `video` and `model_3d` unless no suitable still exists, and MAY provide it for `image` as a low-resolution placeholder. For externally hosted video, `preview.width` and `preview.height` provide the layout aspect ratio.",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "URL of the preview image."
},
"width": {
"type": "integer",
"minimum": 1,
"description": "Actual pixel width of the preview image. The ratio of `preview.width` to `preview.height` is used to reserve embedded-video player layout."
},
"height": {
"type": "integer",
"minimum": 1,
"description": "Actual pixel height of the preview image. The ratio of `preview.width` to `preview.height` is used to reserve embedded-video player layout."
}
}
}
},
"allOf": [
{
"if": {
"properties": { "type": { "const": "image" } },
"required": ["type"]
},
"then": {
"$ref": "media_image.json"
}
},
{
"if": {
"properties": { "type": { "const": "video" } },
"required": ["type"]
},
"then": {
"$ref": "media_video.json"
}
},
{
"if": {
"properties": { "type": { "const": "model_3d" } },
"required": ["type"]
},
"then": {
"$ref": "media_model_3d.json"
}
}
}
]
}
18 changes: 18 additions & 0 deletions source/schemas/common/types/media_image.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/common/types/media_image.json",
"title": "Media Image",
"description": "Type-specific properties for image media.",
"type": "object",
"properties": {
"url": {
"description": "A directly displayable image."
},
"width": {
"description": "Authoritative pixel width of the image."
},
"height": {
"description": "Authoritative pixel height of the image."
}
}
}
19 changes: 19 additions & 0 deletions source/schemas/common/types/media_model_3d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/common/types/media_model_3d.json",
"title": "Media Model 3D",
"description": "Type-specific properties for 3D model media.",
"type": "object",
"properties": {
"url": {
"description": "The primary model file (e.g. GLB)."
},
"sources": {
"type": "array",
"description": "The complete set of available model encodings/file formats (glTF/GLB/USDZ). When present, the Business SHOULD include a source whose `url` equals the media `url`.",
"items": {
"$ref": "media_source.json"
}
}
}
}
Loading
Loading