diff --git a/.gitignore b/.gitignore index ab474137bea2..a90a143b2321 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ .docusaurus .cache-loader static/theoplayer-license.txt +theolive/changelog.md # Misc .DS_Store diff --git a/package.json b/package.json index eca1017a6ae0..a14a2a83fe73 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,15 @@ "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", - "prestart": "npm run gen-api-docs", + "prestart": "npm run gen-api-docs && npm run fetch-theolive-changelog", "build": "docusaurus build", - "prebuild": "npm run gen-api-docs", + "prebuild": "npm run gen-api-docs && npm run fetch-theolive-changelog", "swizzle": "docusaurus swizzle", "clear": "docusaurus clear", "serve": "node serve.js", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", + "fetch-theolive-changelog": "node scripts/fetch-theolive-changelog.mjs", "gen-api-docs": "docusaurus gen-api-docs all --plugin-id ads-api && docusaurus gen-api-docs all --plugin-id ad-engine-api && docusaurus gen-api-docs all --plugin-id millicast-api && docusaurus gen-api-docs all --plugin-id theolive-api --all-versions", "clean-api-docs": "docusaurus clean-api-docs all --plugin-id ads-api && docusaurus clean-api-docs all --plugin-id ad-engine-api && docusaurus clean-api-docs all --plugin-id millicast-api && docusaurus clean-api-docs all --plugin-id theolive-api --all-versions", "typecheck": "tsc", diff --git a/scripts/fetch-theolive-changelog.mjs b/scripts/fetch-theolive-changelog.mjs new file mode 100644 index 000000000000..db8108deb159 --- /dev/null +++ b/scripts/fetch-theolive-changelog.mjs @@ -0,0 +1,22 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const url = 'https://engine-changelog.s3.eu-west-3.amazonaws.com/CHANGELOG.md'; +const outputPath = path.join(__dirname, '..', 'theolive', 'changelog.md'); + +try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to fetch changelog: ${response.status} ${response.statusText}`); + } + const content = await response.text(); + fs.writeFileSync(outputPath, content); + console.log('Fetched THEOlive engine changelog.'); +} catch (error) { + console.warn(`Warning: Could not fetch THEOlive engine changelog: ${error.message}`); + if (!fs.existsSync(outputPath)) { + fs.writeFileSync(outputPath, '# Changelog\n\nChangelog could not be fetched.\n'); + } +} diff --git a/sidebarsTheolive.ts b/sidebarsTheolive.ts index ce2f7368b273..5026e893467f 100644 --- a/sidebarsTheolive.ts +++ b/sidebarsTheolive.ts @@ -80,6 +80,7 @@ const sidebars: SidebarsConfig = { }, href: '/theolive/next/api/', }, + 'changelog', 'api/migration-from-v1', ], theoLiveApi: [ diff --git a/theolive/media-engine/image-overlays.mdx b/theolive/media-engine/image-overlays.mdx new file mode 100644 index 000000000000..aa7a25ba5711 --- /dev/null +++ b/theolive/media-engine/image-overlays.mdx @@ -0,0 +1,66 @@ +--- +sidebar_position: 4 +sidebar_label: Image overlays +sidebar_custom_props: + icon: 🖼️ +description: Add static image overlays like logos or watermarks to your live stream. +--- + +# Image overlays + +Image overlays let you burn static images — such as logos or watermarks — directly into your transcoded stream. Overlays are configured per engine and rendered on top of the video at the specified position and opacity. + +## Configuration + +Each engine supports one or more overlays. An overlay is defined by: + +| Property | Type | Required | Description | +| ---------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------- | +| `url` | `string` | Yes | URL of the overlay image. | +| `position` | `object` | No | Where to place the overlay on the video frame. If omitted, the image is placed at the top-left corner (0, 0). | +| `opacity` | `number` | No | Overlay opacity, from `0` (invisible) to `1` (fully visible). Defaults to `1`. | + +### Position + +The `position` object accepts the following properties, all specified in **pixels**: + +| Property | Type | Description | +| -------- | -------- | ------------------------------------------------------- | +| `top` | `number` | Distance from the top edge of the video frame. | +| `bottom` | `number` | Distance from the bottom edge. Ignored if `top` is set. | +| `left` | `number` | Distance from the left edge of the video frame. | +| `right` | `number` | Distance from the right edge. Ignored if `left` is set. | + +Use a combination of one vertical (`top` or `bottom`) and one horizontal (`left` or `right`) property to anchor the overlay. The pixel values are relative to the **ingest resolution** (i.e. the width and height of the incoming source stream). + +## API example + +Add a logo overlay in the bottom-right corner when [creating](../api/create-channel-engine.api.mdx) or [updating](../api/update-engine.api.mdx) an engine: + +`POST https://api.theo.live/v2/channels/{channelId}/engines` + +```json +{ + "name": "my-engine", + "region": "europe-west", + "quality": { + "abrLadderId": "your-abr-ladder-id" + }, + "overlays": [ + { + "url": "https://example.com/logo.png", + "position": { + "bottom": 20, + "right": 20 + }, + "opacity": 0.8 + } + ] +} +``` + +## Notes + +- Use **PNG images with transparency** for clean overlays that blend naturally with the video. +- The overlay is burned into the transcoded output, so it will appear on all quality levels and all output protocols. +- To remove overlays, update the engine with an empty `overlays` array and restart the engine. diff --git a/theolive/platform/usage.mdx b/theolive/platform/usage.mdx new file mode 100644 index 000000000000..ae498ee3c12e --- /dev/null +++ b/theolive/platform/usage.mdx @@ -0,0 +1,104 @@ +--- +sidebar_position: 20 +sidebar_label: Usage monitoring +sidebar_custom_props: + icon: 📊 +description: Track viewing minutes, bytes transferred, and transcoding minutes per channel. +--- + +# Usage monitoring + +The usage monitoring page lets you track how your streams are consumed and how much transcoding capacity is used. The [dashboard](https://dashboard.optiview.dolby.com/) shows these metrics visually. You can also query them directly through the API. + +Your usage — and pricing — is made up of two independent components: + +1. **Transcoding** — the time your engines spend actively transcoding video. This is measured in **transcoding minutes**. +2. **Viewing** — the consumption by your viewers. Depending on your contract, this is measured either in **viewing minutes** (time spent watching) or **bytes transferred** (data delivered). + +## Common parameters + +All three endpoints share the same base parameters: + +| Parameter | Type | Required | Description | +| ------------ | -------- | -------- | ------------------------------------------------------------------------ | +| `start` | `string` | Yes | Start date for the analytics period. | +| `end` | `string` | Yes | End date for the analytics period. | +| `resolution` | `string` | Yes | Time granularity: `15min`, `hour`, `day`, or `month`. | +| `utcOffset` | `string` | No | UTC offset in minutes. Adjusts how data points align to time boundaries. | + +## Viewing minutes + +Returns how many minutes viewers spent watching a channel's streams. + +`GET https://api.theo.live/v2/channels/{channelId}/analytics/viewing-minutes` + +| Parameter | Type | Required | Description | +| ------------------ | -------- | -------- | ------------------------------------------------------- | +| `groupBy` | `string` | No | `channel`, `distribution`, or `streaming-format`. | +| `distributionIds` | `string` | No | Comma-separated list of distribution IDs to filter by. | +| `streamingFormats` | `string` | No | Comma-separated list of streaming formats to filter by. | + +### Example + +``` +GET /v2/channels/{channelId}/analytics/viewing-minutes?start=2025-01-01&end=2025-01-31&resolution=day&groupBy=distribution +``` + +## Bytes transferred + +Returns the total amount of data delivered to viewers for a channel. + +`GET https://api.theo.live/v2/channels/{channelId}/analytics/bytes-transferred` + +| Parameter | Type | Required | Description | +| ------------------ | -------- | -------- | ------------------------------------------------------- | +| `groupBy` | `string` | No | `channel`, `distribution`, or `streaming-format`. | +| `streamingFormats` | `string` | No | Comma-separated list of streaming formats to filter by. | + +### Example + +``` +GET /v2/channels/{channelId}/analytics/bytes-transferred?start=2025-01-01&end=2025-01-31&resolution=day&groupBy=streaming-format +``` + +## Transcoding minutes + +Returns how many minutes of transcoding capacity was used by a channel's engines. + +`GET https://api.theo.live/v2/channels/{channelId}/analytics/transcoding-minutes` + +| Parameter | Type | Required | Description | +| ----------- | -------- | -------- | ------------------------------------------------ | +| `groupBy` | `string` | No | `engine` or `channel`. | +| `engineIds` | `string` | No | Comma-separated list of engine IDs to filter by. | + +### Example + +``` +GET /v2/channels/{channelId}/analytics/transcoding-minutes?start=2025-01-01&end=2025-01-31&resolution=month&groupBy=engine +``` + +## Response format + +All three endpoints return the same response structure: + +```json +{ + "data": [ + { + "timestamp": "2025-01-01T00:00:00.000Z", + "records": [ + { + "id": "channel-id-or-group-id", + "amount": 1234.5 + } + ] + } + ] +} +``` + +- **`timestamp`** — the start of the time bucket, based on the chosen `resolution`. +- **`records`** — one entry per group (e.g. per distribution, per engine). When no `groupBy` is specified, there is a single record per bucket. + - **`id`** — identifier of the grouped entity (channel ID, distribution ID, engine ID, or streaming format name). + - **`amount`** — the metric value for that time bucket. diff --git a/theolive/platform/viewer-insights.mdx b/theolive/platform/viewer-insights.mdx index cfc83d83b3be..4e74c6566dbb 100644 --- a/theolive/platform/viewer-insights.mdx +++ b/theolive/platform/viewer-insights.mdx @@ -2,7 +2,7 @@ sidebar_position: 7 sidebar_label: Viewer insights sidebar_custom_props: - icon: 📊 + icon: 💡 description: Monitor concurrent viewers, latency, locations and platforms in real time. ---