Catalog 🚧

A Catalog is a manifest-like metadata object a publisher provides as part of the media stream so that a client can discover what media is available before (or without) opening individual subscriptions. It answers: What tracks exist? How are they grouped? What parameters (priority, grouping cadence, naming) apply? A Catalog typically lists:

  • Track identifiers (names)
  • Track attributes (e.g. priority, content type, group period)
  • Relationships (e.g. variants, layers, alt audio, caption tracks)
  • Optional hints for prefetch, caching, or subscription strategy

Using a Catalog avoids trial‑and‑error subscription attempts.

[!TL;DR] Catalogs are JSON objects published on a catalog.json track that describe the available tracks and their metadata. Subscribe to catalog.json to discover media. For now, prefer republishing the full catalog when making changes.

Experimental

gomoqt currently emits its own (unstable) structure. Expect breaking changes until a standard emerges. Unknown fields MUST be ignored for forward compatibility.

Catalog Track

Catalogs are typically published as a special track named catalog.json within a broadcast. To access the catalog, subscribe to this catalog.json track and receive the catalog. This track contains a single JSON object conforming to the schema described below.

Root Object (catalog.json)

FieldTypeRequiredDescription
versionuint62NoFormat version for optimistic evolution. (Default: 1)
descriptionstring (<=500)NoHuman‑readable summary.
tracksmap<string, Track>YesTrack definitions keyed by name.

Track Object

Following fields are defined for each track:

FieldTypeRequiredDescription
namestring (non‑empty)YesTrack identifier (key MUST match).
descriptionstring (<=500)NoHuman description.
priorityuint8 (0‑255)YesRelative selection priority (larger often means more important).
schemastringYesschema id: video, audio, … or URI.
configobjectYesSchema‑specific config (validated per schema).
dependenciesstring[]NoOther track names this track depends on (e.g. captions -> video).

Schema‑Specific Config

Below each schema has its own config shape. These are just examples and may evolve.

Video Schema (schema=“video”)
FieldTypeRequiredDescription
codecstringYesCodec string (e.g. avc1, hvc1, vp09).
descriptionstringNoExtra description.
codedWidthuint53NoEncoded frame width.
codedHeightuint53NoEncoded frame height.
displayAspectWidthuint53NoDisplay aspect numerator.
displayAspectHeightuint53NoDisplay aspect denominator.
framerateuint53NoApprox frames per second.
bitrateuint53NoTarget / observed bitrate (bps).
optimizeForLatencybooleanNoHint to favor latency over quality. (Default: true)
rotationnumberNoRotation degrees CW. (Default: 0)
flipbooleanNoHorizontal flip hint. (Default: false)
containerloc or cmafYesPackaging container.
Audio Schema (schema=“audio”)
FieldTypeRequiredDescription
codecstringYesCodec (e.g. opus, mp4a.40.2).
descriptionstringNoExtra description.
sampleRateuint53YesSampling rate (Hz).
numberOfChannelsuint53YesChannel count.
bitrateuint53NoTarget / observed bitrate.
containerloc or cmafYesPackaging container.
Captions Schema (schema=“captions”)
Captions typically require dependencies referencing at least one media track (audio or video).
Location Schema (schema=“location”)
FieldTypeRequiredDescription
iduint53YesLocation identifier.
namestringYesDisplay name.
avatarurlYesAvatar image URL.
User Schema (schema=“user”)
FieldTypeRequiredDescription
iduuidYesUser id (UUID).
namestringYesDisplay name.
avatarurlYesAvatar image URL.
Timeseries Schema (schema=“timeseries”)
FieldTypeRequiredDescription
measurementsmap<string, Measurement>YesNamed measurement descriptors.

Measurement object:

FieldTypeRequiredDescription
typestringYesMeasurement type identifier.
unitstringYesUnit string (e.g. ms, dB).
intervaluint53YesExpected sampling interval (ms).
minuint53NoLower bound.
maxuint53NoUpper bound.

catalog.json Examples

Web Camera
{
  "version": 1,
  "description": "Example catalog",
  "tracks": {
    "camera-main": {
      "name": "camera-main",
      "priority": 128,
      "schema": "video",
      "config": {
        "codec": "avc1.640028",
        "framerate": 30,
        "container": "cmaf"
      }
    },
    "mic": {
      "name": "mic",
      "priority": 200,
      "schema": "audio",
      "config": {
        "codec": "opus",
        "sampleRate": 48000,
        "numberOfChannels": 2,
        "container": "loc"
      }
    }
  }
}
SVC (Scalable Video Coding)

This example models spatial (and implicitly temporal) layers using multiple video tracks. Each enhancement layer depends on its lower layer via dependencies. The semantics of SVC are application‑level: the MOQ layer only sees independent tracks plus dependencies metadata.

Key points:

  • camera-main-L0 is the base layer (lowest resolution) – highest priority so receivers at constrained bandwidth can still request it first.
  • Enhancement layers (L1, L2) declare dependencies on the immediately lower layer (a receiver MAY ignore those it cannot afford).
  • Codecs are identical; differing codedWidth, codedHeight, and bitrate hint scalability steps.
{
  "version": 1,
  "description": "SVC catalog example (3 spatial layers)",
  "tracks": {
    "camera-main-L0": {
      "name": "camera-main-L0",
      "priority": 200,
      "schema": "video",
      "config": {
        "codec": "avc1.640028",
        "codedWidth": 640,
        "codedHeight": 360,
        "framerate": 30,
        "bitrate": 400000,
        "container": "cmaf"
      }
    },
    "camera-main-L1": {
      "name": "camera-main-L1",
      "priority": 150,
      "schema": "video",
      "dependencies": ["camera-main-L0"],
      "config": {
        "codec": "avc1.640028",
        "codedWidth": 1280,
        "codedHeight": 720,
        "framerate": 30,
        "bitrate": 1200000,
        "container": "cmaf"
      }
    },
    "camera-main-L2": {
      "name": "camera-main-L2",
      "priority": 120,
      "schema": "video",
      "dependencies": ["camera-main-L1"],
      "config": {
        "codec": "avc1.640028",
        "codedWidth": 1920,
        "codedHeight": 1080,
        "framerate": 30,
        "bitrate": 2500000,
        "container": "cmaf"
      }
    },
    "mic": {
      "name": "mic",
      "priority": 210,
      "schema": "audio",
      "config": {
        "codec": "opus",
        "sampleRate": 48000,
        "numberOfChannels": 2,
        "bitrate": 96000,
        "container": "loc"
      }
    }
  }
}

Receiver strategy example:

  1. Subscribe base layer camera-main-L0 and audio mic immediately.
  2. If bandwidth OK, add camera-main-L1; if congestion increases, drop L2 first, then L1.
  3. Dependencies allow a relay to pre‑plan cache / forwarding order (base > enhancements).

Application Semantics

The SVC meaning of dependencies is a convention; MOQ transport does not enforce decoding order. Implementations SHOULD verify lower layers are present before requesting higher ones.

IoT Drone Telemetry (timeseries)

This example shows an IoT / drone telemetry track using the timeseries schema to multiplex several sensor measurements in a single track. A single subscription yields all listed metrics; applications can downsample or filter client‑side.

Design notes:

  • One timeseries track (drone-telemetry) instead of many tiny tracks minimizes subscription signaling.
  • Each entry in measurements describes expected interval and bounds to help receivers allocate buffers / dashboards.
  • Units are illustrative; choose consistent SI units in production.
{
  "version": 1,
  "description": "Drone telemetry catalog example",
  "tracks": {
    "drone-telemetry": {
      "name": "drone-telemetry",
      "priority": 180,
      "schema": "timeseries",
      "config": {
        "measurements": {
          "temperature": { "type": "temperature", "unit": "celsius", "interval": 1000, "min": -40, "max": 85 },
          "humidity": { "type": "humidity", "unit": "percent", "interval": 1500, "min": 0, "max": 100 },
          "altitude": { "type": "altitude", "unit": "meter", "interval": 500, "min": -100, "max": 5000 },
          "latitude": { "type": "latitude", "unit": "degree", "interval": 1000, "min": -90, "max": 90 },
          "longitude": { "type": "longitude", "unit": "degree", "interval": 1000, "min": -180, "max": 180 },
          "battery_voltage": { "type": "battery_voltage", "unit": "volt", "interval": 2000, "min": 0, "max": 30 }
        }
      }
    }
  }
}

Subscription strategy:

  • Critical dashboards subscribe only drone-telemetry early (priority 180).
  • If bandwidth constrained, receiver can locally thin high‑frequency fields (e.g. keep every 2nd altitude sample) without renegotiation.
  • Additional media (video feed) could be another track; telemetry remains unaffected.

Bounds

min/max are informative for UI range scaling; producers MAY omit them. Receivers MUST NOT enforce them as hard validation unless policy demands.

Patch

Catalog changes can be expressed as JSON Patch (RFC 6902) — a compact sequence of operations (add, remove, replace, move, copy, test) that describe a diff against a previous catalog instance.

Example (JSON Patch array):

[
    { "op": "replace", "path": "/tracks/camera-main/priority", "value": 220 },
    { "op": "add", "path": "/tracks/backup-mic", "value": {
        "name": "backup-mic",
        "priority": 150,
        "schema": "audio",
        "config": { "codec": "opus", "sampleRate": 48000, "numberOfChannels": 1, "container": "loc" }
        }
    }
]

Note: Patch Support

Patch updates are not yet supported by this implementation; producers SHOULD republish the full catalog.json until Patch support is added.

Validation & Evolution

Subscribers SHOULD:

  • Ignore unknown top‑level or per‑schema fields.
  • Treat missing optional fields as default values above.
  • Not assume numeric ranges beyond those stated.

Producers SHOULD increment version only on incompatible format changes.

Standardization Status

A unified Catalog format is not standardized yet1 2; disparate implementations (including this one) may diverge3. Alignment work is ongoing.