/proto · contentitem/media.proto
contentitem/media.proto
==============================================================================
Messages
4
Enums
1
Fields
21
Source
3.8 KB
Imports
0
MediaIntent enum · 5 values
==============================================================================
LDF Media Descriptor
Describes any media asset attached to a content item — local blobs,
external URLs, platform embeds, animated images, etc.
Layer responsibilities
─────────────────────
Extractor (C) : sets intent, source, playback. Nothing else.
Service layer (JS) : resolves embed_url, provider, thumb_url from source URL.
Renderer : routes on intent + provider; uses embed_url when set.
The extractor MUST NOT do URL pattern matching or provider detection — that
belongs in the service layer where proper URL parsing libraries are available
and where patterns can be updated without recompiling the extractor.
==============================================================================
What the document author intended this media to be.
Set by the extractor based on the XML element type, not the URL.
| # | name | notes |
|---|---|---|
| 0 | MEDIA_INTENT_UNSPECIFIED | |
| 1 | MEDIA_INTENT_VIDEO | |
| 2 | MEDIA_INTENT_AUDIO | playable video (local or external) |
| 3 | MEDIA_INTENT_IMAGE | playable audio (local or external) |
| 4 | MEDIA_INTENT_EMBED | static or animated image (GIF, etc.) |
MediaSource message · 4 fields
interactive platform embed (player, web app)
used when the URL is not a direct media file
Where the media lives.
| # | label | type | name | notes |
|---|---|---|---|---|
| 1 | single | string | local_path oneof location | Blob is bundled with the document (path within media/ dir). |
| 2 | single | string | external_url oneof location | External URL exactly as written in the document — no processing. The service layer resolves provider/embed_url from this. |
| 3 | optional | bytes | hash | |
| 4 | optional | string | mime_type | BLAKE3-128 of blob (local only) |
MediaBookmark message · 2 fields
MIME type if determinable from extension
Playback control hints extracted from the document.
All fields are optional — renderer falls back to sensible defaults.
| # | label | type | name | notes |
|---|---|---|---|---|
| 1 | optional | string | name | |
| 2 | optional | int32 | time_ms | author-visible bookmark name |
MediaPlayback message · 9 fields
bookmark time relative to media start
| # | label | type | name | notes |
|---|---|---|---|---|
| 1 | optional | bool | loop | |
| 2 | optional | bool | muted | loop playback |
| 3 | optional | bool | show_controls | start muted |
| 4 | optional | int32 | start_ms | show player controls |
| 5 | optional | int32 | end_ms | trim start (ms) |
| 6 | optional | int32 | fade_in_ms | trim end (ms; -1 = play to end) |
| 7 | optional | int32 | fade_out_ms | media fade-in duration |
| 8 | optional | bool | full_screen | media fade-out duration |
| 9 | repeated | MediaBookmark | bookmarks | play video full-screen in slideshow runtimes |
Media message · 6 fields
sparse media bookmark list
Complete media descriptor. Replaces the scattered ContentItem.media_* fields.
| # | label | type | name | notes |
|---|---|---|---|---|
| 1 | single | MediaIntent | intent | Set by extractor ───────────────────────────────────────────────────────── |
| 2 | single | MediaSource | source | render intent |
| 3 | optional | MediaPlayback | playback | where the asset is |
| 10 | optional | string | embed_url | playback hints Set by service layer ───────────────────────────────────────────────────── The C extractor leaves these blank. A post-processing step (Node.js, oEmbed API calls, URL classification library) populates them. Resolved player/embed URL — e.g. "https://www.youtube.com/embed/ID". For local media: absent (use source.local_path via CDN). |
| 11 | optional | string | provider | Human-readable provider hint: "youtube", "vimeo", "giphy", "tenor", etc. Renderer routes embed strategy on this; unknown values fall back to intent-based default. Set by service layer, never hardcoded in extractor. |
| 12 | optional | string | thumb_url | Platform thumbnail URL (from oEmbed or document poster). |
§Raw schema
syntax = "proto3";
package eddocu.media.v3;
// ==============================================================================
// LDF Media Descriptor
//
// Describes any media asset attached to a content item — local blobs,
// external URLs, platform embeds, animated images, etc.
//
// Layer responsibilities
// ─────────────────────
// Extractor (C) : sets intent, source, playback. Nothing else.
// Service layer (JS) : resolves embed_url, provider, thumb_url from source URL.
// Renderer : routes on intent + provider; uses embed_url when set.
//
// The extractor MUST NOT do URL pattern matching or provider detection — that
// belongs in the service layer where proper URL parsing libraries are available
// and where patterns can be updated without recompiling the extractor.
// ==============================================================================
// What the document author intended this media to be.
// Set by the extractor based on the XML element type, not the URL.
enum MediaIntent {
MEDIA_INTENT_UNSPECIFIED = 0;
MEDIA_INTENT_VIDEO = 1; // playable video (local or external)
MEDIA_INTENT_AUDIO = 2; // playable audio (local or external)
MEDIA_INTENT_IMAGE = 3; // static or animated image (GIF, etc.)
MEDIA_INTENT_EMBED = 4; // interactive platform embed (player, web app)
// used when the URL is not a direct media file
}
// Where the media lives.
message MediaSource {
oneof location {
// Blob is bundled with the document (path within media/ dir).
string local_path = 1;
// External URL exactly as written in the document — no processing.
// The service layer resolves provider/embed_url from this.
string external_url = 2;
}
optional bytes hash = 3; // BLAKE3-128 of blob (local only)
optional string mime_type = 4; // MIME type if determinable from extension
}
// Playback control hints extracted from the document.
// All fields are optional — renderer falls back to sensible defaults.
message MediaBookmark {
optional string name = 1; // author-visible bookmark name
optional int32 time_ms = 2; // bookmark time relative to media start
}
message MediaPlayback {
optional bool loop = 1; // loop playback
optional bool muted = 2; // start muted
optional bool show_controls = 3; // show player controls
optional int32 start_ms = 4; // trim start (ms)
optional int32 end_ms = 5; // trim end (ms; -1 = play to end)
optional int32 fade_in_ms = 6; // media fade-in duration
optional int32 fade_out_ms = 7; // media fade-out duration
optional bool full_screen = 8; // play video full-screen in slideshow runtimes
repeated MediaBookmark bookmarks = 9; // sparse media bookmark list
}
// Complete media descriptor. Replaces the scattered ContentItem.media_* fields.
message Media {
// Set by extractor ─────────────────────────────────────────────────────────
MediaIntent intent = 1; // render intent
MediaSource source = 2; // where the asset is
optional MediaPlayback playback = 3; // playback hints
// Set by service layer ─────────────────────────────────────────────────────
// The C extractor leaves these blank. A post-processing step (Node.js,
// oEmbed API calls, URL classification library) populates them.
// Resolved player/embed URL — e.g. "https://www.youtube.com/embed/ID".
// For local media: absent (use source.local_path via CDN).
optional string embed_url = 10;
// Human-readable provider hint: "youtube", "vimeo", "giphy", "tenor", etc.
// Renderer routes embed strategy on this; unknown values fall back to
// intent-based default. Set by service layer, never hardcoded in extractor.
optional string provider = 11;
// Platform thumbnail URL (from oEmbed or document poster).
optional string thumb_url = 12;
}