Skip to content
Merged
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
71 changes: 71 additions & 0 deletions .github/workflows/update-theolive-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Update THEOlive changelog
on:
# Runs every hour
schedule:
- cron: '0 * * * *'
workflow_dispatch:
jobs:
update:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
env:
# The branch that will receive the changelog update (will be created if it doesn't exist)
# Will automatically open a new PR (if no PR exists yet)
UPDATE_BRANCH: update-theolive-changelog
steps:
- name: Create app token
uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ vars.THEOPLAYER_BOT_APP_ID }}
private-key: ${{ secrets.THEOPLAYER_BOT_PRIVATE_KEY }}
- name: Checkout
uses: actions/checkout@v6
with:
token: ${{ steps.app-token.outputs.token }}
fetch-depth: 1
- name: Configure Git user
run: |
git config user.name 'theoplayer-bot[bot]'
git config user.email '873105+theoplayer-bot[bot]@users.noreply.github.com'
- name: Fetch THEOlive changelog
run: |
curl -fsSL -o theolive/changelog.md \
'https://engine-changelog.s3.eu-west-3.amazonaws.com/CHANGELOG.md'
- name: Check for changes
id: check_changes
run: |
if git diff --quiet theolive/changelog.md; then
echo "No changelog changes detected."
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Commit and push changes
if: ${{ steps.check_changes.outputs.changed }}
run: |
git checkout -b $UPDATE_BRANCH
git add theolive/changelog.md
git commit -m 'Update THEOlive changelog'
git push --force origin HEAD:$UPDATE_BRANCH
- name: Check if pull request already exists
if: ${{ steps.check_changes.outputs.changed }}
id: check_pr_exists
run: |
pr_count=$(gh pr list --base main --head "$UPDATE_BRANCH" --state open --limit 1 --json number --jq length)
if ((pr_count > 0)); then
echo "exists=true" >> "$GITHUB_OUTPUT"
fi
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
- name: Create pull request
if: ${{ steps.check_changes.outputs.changed && !steps.check_pr_exists.outputs.exists }}
run: |
gh pr create \
--base main \
--head "$UPDATE_BRANCH" \
--title "Update THEOlive changelog" \
--body "This PR pulls in the latest THEOlive engine changelog."
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
.docusaurus
.cache-loader
static/theoplayer-license.txt
theolive/changelog.md

# Misc
.DS_Store
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"prestart": "npm run gen-api-docs && npm run fetch-theolive-changelog",
"prestart": "npm run gen-api-docs",
"build": "docusaurus build",
"prebuild": "npm run gen-api-docs && npm run fetch-theolive-changelog",
"prebuild": "npm run gen-api-docs",
"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",
Expand Down
22 changes: 0 additions & 22 deletions scripts/fetch-theolive-changelog.mjs

This file was deleted.

7 changes: 6 additions & 1 deletion sidebarsTheolive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ const sidebars: SidebarsConfig = {
icon: '📺',
},
description: 'Configure channel-level settings and optional features.',
link: { type: 'generated-index', slug: 'channel' },
link: {
type: 'generated-index',
slug: 'channel',
description:
'A channel is the core building block of the platform — it represents a complete live streaming pipeline from media ingestion through to viewer delivery. Each channel is composed of ingests, engines, and distributions. This section covers settings configured at the channel level. See the Architecture page for the full breakdown.',
},
items: [{ type: 'autogenerated', dirName: 'channel' }],
},
{
Expand Down
Binary file added theolive/assets/img/image-overlays.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions theolive/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Changelog

## [10.13.0] - 2026-03-25

- Added image overlay support
- Upgraded to GStreamer 1.28.1
- Upgraded to Rust 1.94

## [10.12.0] - 2026-03-06

- Optimized encode of HLS when HESP is disabled
- Allow enabling / disabling of individual protocols
- Improved quality of de-interlacing
- Improved quality of video scaler
- Upgraded to GStreamer 1.28
- Simplified stream config
- VMAF
- eRTMP built-in from GStreamer
- Improved logging
- Disable PlayReady
- Deprecate /streams

## [10.9.0] - 2026-01-30

- Initial changelog
10 changes: 10 additions & 0 deletions theolive/channel/dvr.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,18 @@ To enable DVR, set a **window size** in seconds on your channel. This determines

</figure>

The DVR window size is configured at the channel level and applies equally to all distributions. You cannot set different window sizes for different distributions. However, you can enable or disable DVR on a per-distribution basis.

In addition to setting the window size on the channel, DVR must also be **enabled on each distribution** where you want viewers to have time-shifted playback. Distributions without DVR enabled will serve a live-only stream, even if the channel has a DVR window configured.

When DVR is enabled, viewers can scrub back through the live stream within the configured window. Once the window is exceeded, older content is no longer available for playback.

:::caution[Large DVR windows]
Very large DVR windows produce large HLS/DASH playlists, which can result in degraded performance on some players and devices. Chromecasts in particular are known to have issues with long DVR windows.

If you need a long DVR window, test thoroughly on your target devices before going to production.
:::

## API example

You can also enable DVR via the API by setting `dvr.enabled` to `true` and `dvr.windowInSeconds` to your desired window size (60–86400 seconds) when [creating](../api/create-channel.api.mdx) or [updating](../api/update-channel.api.mdx) your channel.
Expand Down
8 changes: 8 additions & 0 deletions theolive/contribution/ingest-protocols.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ description: Supported ingest protocols (RTMP and SRT) and their trade-offs.

The Dolby OptiView Live platform supports low latency live streaming through two ingest protocols: **RTMP** and **SRT**.

RTMP supports both **pull** and **push** mode out of the box. SRT works out of the box in **pull mode** only, where the platform connects to your encoder to pull the stream. If you need SRT push mode, contact your account representative to have it enabled.

## RTMP — Real-Time Messaging Protocol

RTMP is a widely adopted protocol originally developed by Adobe for transmitting audio, video, and data over the internet. It remains one of the most commonly supported protocols across hardware and software encoders.
Expand All @@ -34,3 +36,9 @@ SRT is an open-source protocol designed for low latency, secure, and reliable vi
- **Cons**
- **Less universal encoder support** — While adoption is growing, not all encoders support SRT, especially older hardware models.
- **More complex configuration** — SRT may require tuning parameters such as latency, overhead bandwidth, and encryption settings for optimal performance.

### SRT passphrase

In **pull mode**, you can secure the connection by including the passphrase directly in the SRT URL that you configure on your channel (e.g. `srt://encoder-host:port?passphrase=my-secret`).

In **push mode**, the Dolby team configures the passphrase for you and provides an SRT URL with the passphrase included.
6 changes: 4 additions & 2 deletions theolive/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ sidebar_custom_props:
description: Create your first stream, from setup to embedding the player.
---

OptiView Live Streaming is the new name for THEOlive Streaming as part of the OptiView product suite. During the transition, you may still see references to THEOlive. OptiView Live and THEOlive refer to the same product.

# Getting started

This guide walks you through creating your first stream, from setting up an account to embedding the player on your page.
Expand Down Expand Up @@ -78,8 +80,8 @@ The engine is responsible for transcoding and packaging the incoming media. Crea
- **Enable DRM** — secure your content with Digital Rights Management.
- **Enable HESP** — output content in HESP format for low latency delivery.
- **Enable HLS** — output content in HLS format for broad platform compatibility.
- **Enable HLS MPEG-TS** — output content in HLS MPEG-TS format. Only recommended for very specific platforms that don't support HLS with CMAF segments.
- **DAI Asset Key** — asset key for Dynamic Ad Insertion.
- **Enable HLS MPEG-TS** — output content in HLS MPEG-TS format. Only recommended for very specific platforms that don't support HLS with CMAF segments. This feature needs to be explicitly enabled in your account by an admin and isn't compatible with some other features like DRM.
- **DAI Asset Key** — asset key for OptiView ads. To learn more, contact your Dolby team.

</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions theolive/media-engine/drm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ description: Protect your live streams with Digital Rights Management.

Digital Rights Management (DRM) protects live video content by encrypting the stream so that only authorized viewers can watch it. Without DRM, streams can be intercepted, redistributed, or recorded without permission.

:::info
DRM is a fully managed, premium feature. Contact your account representative to learn more and get started.
:::

DRM is essential for content that requires legal or contractual protection, such as premium sports broadcasts, pay-per-view events, or licensed entertainment. It ensures that content owners retain control over who can access their streams and under what conditions.

## Enabling DRM
Expand Down
8 changes: 4 additions & 4 deletions theolive/media-engine/encoding-quality.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ If low latency is not a requirement for your use case, configure your engine to

## Choosing the right configuration

| Use case | Recommended outputs | Latency | Image quality |
| ---------------------------------------------- | ------------------- | ----------------- | ------------- |
| Live sports betting, interactive entertainment | HESP + HLS | Ultra-low (1–5s) | Good |
| Linear broadcast, non-interactive live events | HLS only | Standard (10–30s) | Higher |
| Use case | Recommended outputs | Latency | Image quality |
| ---------------------------------------------- | ------------------- | ---------------- | ------------- |
| Live sports betting, interactive entertainment | HESP + HLS | Ultra-low (1–5s) | Good |
| Linear broadcast, non-interactive live events | HLS only | Standard (8s+) | Higher |

:::tip
You can create multiple engines on the same channel with different output configurations. For example, use one engine with HESP for low-latency viewers and another with HLS only for viewers who prioritize quality over latency. Attach each to a separate distribution to serve both audiences from the same ingest.
Expand Down
8 changes: 8 additions & 0 deletions theolive/media-engine/image-overlays.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ description: Add static image overlays like logos or watermarks to your live str

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.

## Dashboard

You can configure overlays directly from the dashboard by editing an engine and opening the **Overlays** dialog. For each overlay, provide the image URL, choose a position preset (e.g. Top Left, Bottom Right), and optionally adjust the opacity and dimensions.

![Edit Overlays dialog](../assets/img/image-overlays.png)

Use **+ Add Overlay** to add multiple overlays to the same engine. Click **Save** to apply your changes.

## Configuration

Each engine supports one or more overlays. An overlay is defined by:
Expand Down
2 changes: 1 addition & 1 deletion theolive/media-engine/streaming-protocols.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ HESP is a next-generation streaming protocol designed for ultra-low latency live
HLS is the industry-standard protocol developed by Apple for delivering live and on-demand content over HTTP. The media engine outputs HLS using modern CMAF (fragmented MP4) segments.

- **Broad compatibility** — supported by virtually all modern browsers, devices and players.
- **Higher latency**compared to HESP, HLS typically introduces several seconds of additional latency.
- **Higher latency** — HLS typically delivers latency of 8 seconds or more, compared to 1–5 seconds with HESP.

### HLS (MPEG-TS)

Expand Down
44 changes: 27 additions & 17 deletions theolive/platform/real-time-update-with-webhooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ description: Receive real-time notifications when channel events occur.

Webhooks let you receive real-time notifications when events happen in your streaming infrastructure. Instead of polling for changes, you register an endpoint URL and the system pushes event data to it automatically.

For the full endpoint specification, see the [Webhooks API reference](../api/create-webhook.api.mdx).

## What is a Webhook?

A webhook is an HTTP callback that sends a `POST` request to your endpoint whenever a subscribed event occurs — for example, when a channel starts, an engine encounters an error, or a distribution is updated.
Expand Down Expand Up @@ -102,7 +104,7 @@ You can also use the **wildcard** (`*`) to listen to all events at once.

After creation, you are redirected to the webhook detail page where you can view the signing secret.

### API example — Create a webhook
### API example — [Create a webhook](../api/create-webhook.api.mdx)

**Listen to specific events:**

Expand Down Expand Up @@ -138,7 +140,7 @@ The **Webhooks** page shows a table of all your webhooks with:
- **Events** — Shows "All events" for wildcard webhooks, or the count of subscribed events.
- **Actions** — Edit or delete the webhook.

### API example — List all webhooks
### API example — [List all webhooks](../api/get-webhooks.api.mdx)

`GET https://api.theo.live/v2/webhooks`

Expand All @@ -149,7 +151,7 @@ Optional query parameters:
| `cursor` | [Pagination](../api/pagination.mdx) cursor for the next page |
| `limit` | Number of results per page |

### API example — Get a single webhook
### API example — [Get a single webhook](../api/get-webhook.api.mdx)

`GET https://api.theo.live/v2/webhooks/{webhookId}`

Expand Down Expand Up @@ -186,7 +188,7 @@ You can change:

Click **Save** to apply your changes.

### API example — Update a webhook
### API example — [Update a webhook](../api/update-webhook.api.mdx)

All fields are optional; only include the fields you want to change.

Expand All @@ -209,7 +211,7 @@ When editing a webhook, you can toggle the **Active / Inactive** switch.

This is useful when you want to temporarily stop receiving events without deleting the webhook.

### API example — Activate or deactivate a webhook
### API example — [Activate or deactivate a webhook](../api/update-webhook.api.mdx)

Use the update endpoint with the `active` field:

Expand All @@ -229,7 +231,7 @@ Click the **trash icon** on the webhooks list, or click **Delete** on the webhoo

> **Note:** You must deactivate a webhook before deleting it.

### API example — Delete a webhook
### API example — [Delete a webhook](../api/delete-webhook.api.mdx)

`DELETE https://api.theo.live/v2/webhooks/{webhookId}`

Expand All @@ -240,22 +242,30 @@ When an event fires, Dolby sends a `POST` request to your endpoint with a JSON b
```json
{
"type": "channel.stopped",
"created": 1711900800,
"createdAt": 1711900800,
"object": {
"type": "channel",
"id": "ch_abc123"
"id": "ch_abc123",
"name": "name-of-channel",
"organizationId": "organization-id",
// optionally information about the parent object (id, type and name)
},
"data": { ... }
"data": { ... },
}
```

| Field | Description |
| ------------- | ------------------------------------------------------------------------------ |
| `type` | The event type string (e.g. `channel.stopped`, `engine.error`) |
| `created` | Unix timestamp of when the event occurred |
| `object.type` | The resource type: `channel`, `engine`, `ingest`, `distribution`, or `webhook` |
| `object.id` | The ID of the resource that triggered the event |
| `data` | Event-specific payload with additional details |
| Field | Description |
| ----------------------- | ------------------------------------------------------------------------------ |
| `type` | The event type string (e.g. `channel.stopped`, `engine.error`) |
| `createdAt` | Unix timestamp of when the event occurred |
| `object.type` | The resource type: `channel`, `engine`, `ingest`, `distribution`, or `webhook` |
| `object.id` | The ID of the resource that triggered the event |
| `object.name` | The name of the resource that triggered the event |
| `object.organizationId` | The ID of the organization that owns the resource |
| `object.parent.id` | Optionally: the ID of the parent resource that triggered the event |
| `object.parent.name` | Optionally: the name of the parent resource that triggered the event |
| `object.parent.type` | Optionally: the type of the parent resource that triggered the event |
| `data` | Event-specific payload with additional details |

## Verifying Webhook Signatures

Expand Down Expand Up @@ -331,7 +341,7 @@ app.listen(port, () => {
});
```

### API example — Get the webhook secret
### API example — [Get the webhook secret](../api/get-webhook-secret.api.mdx)

`GET https://api.theo.live/v2/webhooks/{webhookId}/secret`

Expand Down
Loading
Loading