From b4192556482fb921b975b097354da093606b3aad Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:40 +0000 Subject: [PATCH 01/19] Add audio-only player example Co-Authored-By: ceyhun.ozgoc --- theoplayer/examples/ui/07-audio-only.mdx | 52 +++++++++ .../v11/examples/audio-only/demo.html | 103 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 theoplayer/examples/ui/07-audio-only.mdx create mode 100644 theoplayer/static/theoplayer/v11/examples/audio-only/demo.html diff --git a/theoplayer/examples/ui/07-audio-only.mdx b/theoplayer/examples/ui/07-audio-only.mdx new file mode 100644 index 000000000000..2036df2a5828 --- /dev/null +++ b/theoplayer/examples/ui/07-audio-only.mdx @@ -0,0 +1,52 @@ +--- +sidebar_custom_props: { icon: '🎧' } +description: Build an audio-only player with Open Video UI. +--- + +# Audio-only player + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/audio-only/demo.html'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Example from '@site/src/components/Example'; + + + +With Open Video UI you compose a player from only the controls you need. This example uses a bare +`` element with a track info area in the top chrome and a control bar containing just +a play button, a seek bar, a time display, a mute button and a volume slider β€” no video area, +center play button or fullscreen button. + +The video area is collapsed with CSS custom properties, so no `display: none` overrides are needed: + +```css +theoplayer-ui { + --theoplayer-aspect-ratio: none; + --theoplayer-video-height: 0; + --theoplayer-video-width: 0; + --theoplayer-height: auto; +} +``` + +```html + +
...
+ + + + + + + +
+``` + +`user-idle-timeout="-1"` disables the idle timer and `no-auto-hide` on the controls keeps them +visible at all times, since there is no video to tap when the controls fade out. + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html b/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html new file mode 100644 index 000000000000..424235a1f216 --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html @@ -0,0 +1,103 @@ + + + + + Audio-only player + + + + + + + + + + + + +
+ +
+
Elephants Dream
+
Open Movie Project · Soundtrack
+
+
+ + + + + + + +
+ + + From 3a8f62a60064f2d82ed4653eaa2547c1843fda97 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:41 +0000 Subject: [PATCH 02/19] Add keep the control bar visible example Co-Authored-By: ceyhun.ozgoc --- .../ui/08-keep-control-bar-visible.mdx | 51 +++++++++++++++++++ .../keep-control-bar-visible/default-ui.html | 43 ++++++++++++++++ .../keep-control-bar-visible/demo.html | 50 ++++++++++++++++++ .../ui/web/keep-control-bar-visible.mdx | 19 ++++++- 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 theoplayer/examples/ui/08-keep-control-bar-visible.mdx create mode 100644 theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/default-ui.html create mode 100644 theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/demo.html diff --git a/theoplayer/examples/ui/08-keep-control-bar-visible.mdx b/theoplayer/examples/ui/08-keep-control-bar-visible.mdx new file mode 100644 index 000000000000..932b5c27d1a4 --- /dev/null +++ b/theoplayer/examples/ui/08-keep-control-bar-visible.mdx @@ -0,0 +1,51 @@ +--- +sidebar_custom_props: { icon: 'πŸ‘€' } +description: Keep the control bar visible at all times. +--- + +# Keep the control bar visible + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/keep-control-bar-visible/demo.html'; +import defaultUiSource from '!!raw-loader!../../static/theoplayer/v11/examples/keep-control-bar-visible/default-ui.html'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Example from '@site/src/components/Example'; + +By default the control bar fades out after a few seconds of inactivity. These examples keep it visible at all times. + +## Open Video UI + + + +Set `user-idle-timeout` to a negative value to disable idle detection, so the controls never fade out. + +```html +... +``` + +
+ Code + + {demoSource} + +
+ +## Default UI + + + +In the [Default UI](../../ui/web/default-ui/index.mdx), override the fade-out transition with two CSS lines. + +```css +.theo-secondary-color.vjs-control-bar { + opacity: 1 !important; + visibility: visible !important; +} +``` + +
+ Code + + {defaultUiSource} + +
diff --git a/theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/default-ui.html b/theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/default-ui.html new file mode 100644 index 000000000000..35010fe35d40 --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/default-ui.html @@ -0,0 +1,43 @@ + + + + + Keep control bar visible (Default UI) + + + + + + +
+ + + diff --git a/theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/demo.html b/theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/demo.html new file mode 100644 index 000000000000..ee93207710ff --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/keep-control-bar-visible/demo.html @@ -0,0 +1,50 @@ + + + + + Keep control bar visible + + + + + + + + + + + + + + + diff --git a/theoplayer/ui/web/keep-control-bar-visible.mdx b/theoplayer/ui/web/keep-control-bar-visible.mdx index 0bf81a0cf987..2ec1ae96d463 100644 --- a/theoplayer/ui/web/keep-control-bar-visible.mdx +++ b/theoplayer/ui/web/keep-control-bar-visible.mdx @@ -7,12 +7,27 @@ sidebar_label: Keep the control bar visible The question above is typically asked by developers who want to be able to see the control bar at all times without having to continuously move the cursor over it (or tap the screen). -## Implementation +## Open Video UI -The following CSS line is aimed at overwriting the opacity transition and have the control bar always visible. +Set the `user-idle-timeout` attribute (or the `userIdleTimeout` property) to a negative value. This disables idle detection, so the control bar never fades out. + +```html + +``` + +```js +ui.userIdleTimeout = -1; +``` + +## Default UI + +The following CSS lines overwrite the fade-out transition and keep the control bar always visible. ```css .theo-secondary-color.vjs-control-bar { opacity: 1 !important; + visibility: visible !important; } ``` + +See the [Keep the control bar visible](../../examples/ui/08-keep-control-bar-visible.mdx) example for a working demo of both UIs. From a75c7ebc23f999834d1d0bcef179b07a7844be13 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:41 +0000 Subject: [PATCH 03/19] Add Conviva analytics example Co-Authored-By: ceyhun.ozgoc --- .../examples/_components/ConvivaDemo.tsx | 128 +++++++++++++++++ theoplayer/examples/analytics/01-conviva.mdx | 46 +++++++ theoplayer/examples/analytics/_category_.json | 7 + .../theoplayer/v11/examples/conviva/demo.html | 129 ++++++++++++++++++ 4 files changed, 310 insertions(+) create mode 100644 theoplayer/examples/_components/ConvivaDemo.tsx create mode 100644 theoplayer/examples/analytics/01-conviva.mdx create mode 100644 theoplayer/examples/analytics/_category_.json create mode 100644 theoplayer/static/theoplayer/v11/examples/conviva/demo.html diff --git a/theoplayer/examples/_components/ConvivaDemo.tsx b/theoplayer/examples/_components/ConvivaDemo.tsx new file mode 100644 index 000000000000..01024bf80676 --- /dev/null +++ b/theoplayer/examples/_components/ConvivaDemo.tsx @@ -0,0 +1,128 @@ +import React, { type JSX, useRef, useState } from 'react'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Example, { type ExampleController } from '@site/src/components/Example'; +import styles from '../shared.module.css'; + +interface StreamTemplate { + id: string; + label: string; + assetName: string; + streamType: 'VOD' | 'LIVE'; + source: { + sources: { src: string; type: string }; + poster?: string; + metadata: { title: string }; + }; +} + +interface EventEntry { + time: string; + event: string; + details: string; +} + +const templates: StreamTemplate[] = [ + { + id: 'hls-vod', + label: 'HLS VOD (Big Buck Bunny)', + assetName: 'Big Buck Bunny (HLS)', + streamType: 'VOD', + source: { + sources: { src: 'https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_corrected.m3u8', type: 'application/x-mpegurl' }, + poster: 'https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg', + metadata: { title: 'Big Buck Bunny' }, + }, + }, + { + id: 'hls-live', + label: 'HLS live (Unified Streaming)', + assetName: 'Live stream (HLS)', + streamType: 'LIVE', + source: { + sources: { src: 'https://demo.unified-streaming.com/k8s/live/stable/live.isml/.m3u8', type: 'application/x-mpegurl' }, + metadata: { title: 'Live stream' }, + }, + }, + { + id: 'dash-vod', + label: 'DASH VOD (Big Buck Bunny)', + assetName: 'Big Buck Bunny (DASH)', + streamType: 'VOD', + source: { + sources: { src: 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd', type: 'application/dash+xml' }, + poster: 'https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg', + metadata: { title: 'Big Buck Bunny' }, + }, + }, + { + id: 'dash-live', + label: 'DASH live (Unified Streaming)', + assetName: 'Live stream (DASH)', + streamType: 'LIVE', + source: { + sources: { src: 'https://demo.unified-streaming.com/k8s/live/stable/live.isml/.mpd', type: 'application/dash+xml' }, + metadata: { title: 'Live stream' }, + }, + }, +]; + +export default function ConvivaDemo(): JSX.Element { + const exampleRef = useRef(null); + const [templateId, setTemplateId] = useState(templates[0].id); + const [events, setEvents] = useState([]); + + function selectTemplate(id: string): void { + setTemplateId(id); + const template = templates.find((entry) => entry.id === id); + if (!template) return; + setEvents([]); + exampleRef.current?.postMessage({ + type: 'load-source', + stream: { assetName: template.assetName, streamType: template.streamType, source: template.source }, + }); + } + + return ( + <> + { + if (message.type === 'conviva-events' && Array.isArray(message.events)) { + setEvents(message.events as EventEntry[]); + } + }} + /> +
+
+ Stream templates +
+ {templates.map((template) => ( + + ))} +
+
+
+ {events.length === 0 ? ( + No events reported yet. + ) : ( + events.map((entry, index) => ( +
+ {entry.time} + {entry.event} + {entry.details || 'β€”'} +
+ )) + )} +
+
+ + ); +} diff --git a/theoplayer/examples/analytics/01-conviva.mdx b/theoplayer/examples/analytics/01-conviva.mdx new file mode 100644 index 000000000000..83296cffa84d --- /dev/null +++ b/theoplayer/examples/analytics/01-conviva.mdx @@ -0,0 +1,46 @@ +--- +sidebar_custom_props: { icon: 'πŸ“Š' } +description: Monitor playback with the Conviva connector. +--- + +# Conviva + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/conviva/demo.html'; +import ConvivaDemo from '../_components/ConvivaDemo'; + + + +This example reports playback to [Conviva](https://pulse.conviva.com/) using the +[Conviva connector for THEOplayer](https://www.npmjs.com/package/@theoplayer/conviva-connector-web). +The connector bridges player events to the Conviva SDK: it starts a session when playback begins +and reports content metadata, buffering and errors automatically. + +```js +const convivaIntegration = new THEOplayerConvivaConnector.ConvivaConnector(player, convivaMetadata, convivaConfig); + +// Source-specific metadata does not carry over to the next source, +// so set it again after every sourcechange. +player.addEventListener('sourcechange', () => { + convivaIntegration.setContentInfo({ + ['Conviva.assetName']: 'Big Buck Bunny', + ['Conviva.streamUrl']: source.sources.src, + ['Conviva.streamType']: 'VOD', + }); +}); +``` + +The `convivaConfig` in this demo uses a Conviva test customer key and Touchstone gateway URL β€” +replace them with your own credentials (and omit `gatewayUrl` for production). +Use the stream templates to switch between HLS/DASH and VOD/live sources; the metadata is updated on each `sourcechange`. + +:::note +With `debug: true`, Conviva SDK debug logs are printed in the browser's DevTools console. +::: + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/examples/analytics/_category_.json b/theoplayer/examples/analytics/_category_.json new file mode 100644 index 000000000000..df97ffdb0aef --- /dev/null +++ b/theoplayer/examples/analytics/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Analytics", + "position": 9, + "customProps": { + "icon": "πŸ“Š" + } +} diff --git a/theoplayer/static/theoplayer/v11/examples/conviva/demo.html b/theoplayer/static/theoplayer/v11/examples/conviva/demo.html new file mode 100644 index 000000000000..600952511dde --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/conviva/demo.html @@ -0,0 +1,129 @@ + + + + + Conviva + + + + + + + + + + + + + + + + + + + + From 64e20dd69e55444a6fc6136bfd98d838d0c32953 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:41 +0000 Subject: [PATCH 04/19] Add Millicast example Co-Authored-By: ceyhun.ozgoc --- .../examples/streaming/08-millicast.mdx | 38 ++++++++++++++ .../v11/examples/millicast/demo.html | 49 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 theoplayer/examples/streaming/08-millicast.mdx create mode 100644 theoplayer/static/theoplayer/v11/examples/millicast/demo.html diff --git a/theoplayer/examples/streaming/08-millicast.mdx b/theoplayer/examples/streaming/08-millicast.mdx new file mode 100644 index 000000000000..91d65ead03cf --- /dev/null +++ b/theoplayer/examples/streaming/08-millicast.mdx @@ -0,0 +1,38 @@ +--- +sidebar_custom_props: { icon: 'πŸ“‘' } +description: Play a sub-second latency Millicast live stream. +--- + +# Millicast + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/millicast/demo.html'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Example from '@site/src/components/Example'; + + + +[Millicast](pathname:///millicast/getting-started/) delivers real-time streaming with sub-second latency over WebRTC. +THEOplayer can subscribe to a Millicast stream directly: set the source `type` to `"millicast"` and +provide the stream name (`src`) and account identifier (`streamAccountId`). + +```js +player.source = { + sources: { + type: 'millicast', + src: 'multiview', + streamAccountId: 'k9Mwad', + // subscriberToken: '...' // for secure streams + }, +}; +``` + +See the [`MillicastSource`](pathname:///theoplayer/v11/api-reference/web/interfaces/MillicastSource.html) +API reference for all available fields, including `subscriberToken` for secure streams. + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/static/theoplayer/v11/examples/millicast/demo.html b/theoplayer/static/theoplayer/v11/examples/millicast/demo.html new file mode 100644 index 000000000000..f48beb02d7a7 --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/millicast/demo.html @@ -0,0 +1,49 @@ + + + + + Millicast + + + + + + + + + + + + + + + From 33baedcb5d0b4d185d67a980739c99599ae03ee0 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:42 +0000 Subject: [PATCH 05/19] Add THEOlive example with latency readout Co-Authored-By: ceyhun.ozgoc --- .../examples/_components/TheoLiveDemo.tsx | 31 ++++++++++ theoplayer/examples/streaming/09-theolive.mdx | 36 ++++++++++++ .../v11/examples/theolive/demo.html | 56 +++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 theoplayer/examples/_components/TheoLiveDemo.tsx create mode 100644 theoplayer/examples/streaming/09-theolive.mdx create mode 100644 theoplayer/static/theoplayer/v11/examples/theolive/demo.html diff --git a/theoplayer/examples/_components/TheoLiveDemo.tsx b/theoplayer/examples/_components/TheoLiveDemo.tsx new file mode 100644 index 000000000000..39a4a4cfc741 --- /dev/null +++ b/theoplayer/examples/_components/TheoLiveDemo.tsx @@ -0,0 +1,31 @@ +import React, { type JSX, useState } from 'react'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Example from '@site/src/components/Example'; +import styles from '../shared.module.css'; + +export default function TheoLiveDemo(): JSX.Element { + const [latency, setLatency] = useState(null); + + return ( + <> + { + if (message.type === 'latency') { + setLatency(typeof message.latency === 'number' ? message.latency : null); + } + }} + /> +
+ + + + + + + +
player.latency.currentLatency{latency == null ? 'β€”' : `${latency.toFixed(2)} s`}
+
+ + ); +} diff --git a/theoplayer/examples/streaming/09-theolive.mdx b/theoplayer/examples/streaming/09-theolive.mdx new file mode 100644 index 000000000000..ac5abf76bdd6 --- /dev/null +++ b/theoplayer/examples/streaming/09-theolive.mdx @@ -0,0 +1,36 @@ +--- +sidebar_custom_props: { icon: 'πŸ“Ί' } +description: Play a THEOlive real-time stream and see the current latency. +--- + +# THEOlive + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/theolive/demo.html'; +import TheoLiveDemo from '../_components/TheoLiveDemo'; + + + +[THEOlive](../../how-to-guides/web/theolive/getting-started.mdx) delivers real-time video at sub-second latency. +Set the source `type` to `"theolive"` and `src` to your channel or distribution ID. + +```js +player.source = { + sources: { + type: 'theolive', + src: 'ar5c53uzm3si4h4zgkzrju44h', + }, +}; +``` + +The readout below the player shows `player.latency.currentLatency`, the end-to-end latency in seconds, +updated on every `timeupdate` event. +See the [`TheoLiveSource`](pathname:///theoplayer/v11/api-reference/web/interfaces/TheoLiveSource.html) +API reference for all available fields. + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/static/theoplayer/v11/examples/theolive/demo.html b/theoplayer/static/theoplayer/v11/examples/theolive/demo.html new file mode 100644 index 000000000000..c379dd9c681f --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/theolive/demo.html @@ -0,0 +1,56 @@ + + + + + THEOlive + + + + + + + + + + + + + + + + From a921513bbba89c9429fe459e2548f1f8f60c2bde Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:42 +0000 Subject: [PATCH 06/19] Add Dolby Atmos, Dolby Vision and HDR detection examples Co-Authored-By: ceyhun.ozgoc --- spellcheck/dictionary.txt | 4 + .../examples/_components/DetectionDemo.tsx | 98 ++++++++++++++ theoplayer/examples/shared.module.css | 5 + .../examples/streaming/10-dolby-atmos.mdx | 63 +++++++++ .../examples/streaming/11-dolby-vision.mdx | 62 +++++++++ theoplayer/examples/streaming/12-hdr.mdx | 45 +++++++ .../v11/examples/dolby-atmos/demo.html | 108 +++++++++++++++ .../v11/examples/dolby-vision/demo.html | 126 ++++++++++++++++++ .../theoplayer/v11/examples/hdr/demo.html | 116 ++++++++++++++++ 9 files changed, 627 insertions(+) create mode 100644 theoplayer/examples/_components/DetectionDemo.tsx create mode 100644 theoplayer/examples/streaming/10-dolby-atmos.mdx create mode 100644 theoplayer/examples/streaming/11-dolby-vision.mdx create mode 100644 theoplayer/examples/streaming/12-hdr.mdx create mode 100644 theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html create mode 100644 theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html create mode 100644 theoplayer/static/theoplayer/v11/examples/hdr/demo.html diff --git a/spellcheck/dictionary.txt b/spellcheck/dictionary.txt index 7f88b2f437f6..15472243d513 100644 --- a/spellcheck/dictionary.txt +++ b/spellcheck/dictionary.txt @@ -1021,3 +1021,7 @@ yospace-connector-web Yottabyte Youbora Zettabyte +HLG +HLG-compatible +PQ +UIs diff --git a/theoplayer/examples/_components/DetectionDemo.tsx b/theoplayer/examples/_components/DetectionDemo.tsx new file mode 100644 index 000000000000..2c34945eff1a --- /dev/null +++ b/theoplayer/examples/_components/DetectionDemo.tsx @@ -0,0 +1,98 @@ +import React, { type JSX, useRef, useState } from 'react'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Example, { type ExampleController } from '@site/src/components/Example'; +import styles from '../shared.module.css'; + +type CheckStatus = 'supported' | 'unsupported' | 'unavailable'; + +interface Check { + label: string; + status: CheckStatus; +} + +interface SourceOption { + label: string; + source: unknown; +} + +interface Props { + src: string; + sources?: SourceOption[]; +} + +const alertClass = { + success: 'alert--success', + warning: 'alert--warning', + danger: 'alert--danger', + unknown: 'alert--info', +} as const; + +const checkIcon: Record = { + supported: 'βœ”', + unsupported: '✘', + unavailable: 'β€”', +}; + +export default function DetectionDemo({ src, sources }: Props): JSX.Element { + const exampleRef = useRef(null); + const [level, setLevel] = useState('unknown'); + const [summary, setSummary] = useState('Checking support…'); + const [checks, setChecks] = useState([]); + const [codecs, setCodecs] = useState(''); + const [activeSource, setActiveSource] = useState(0); + + return ( + <> +
+ {summary} + {checks.length > 0 && ( +
    + {checks.map((check) => ( +
  • + {checkIcon[check.status]} {check.label} +
  • + ))} +
+ )} + {codecs &&
Now playing: {codecs}
} +
+ { + if (message.type === 'detection-status') { + const nextLevel = + typeof message.level === 'string' && message.level in alertClass ? (message.level as keyof typeof alertClass) : 'unknown'; + setLevel(nextLevel); + if (typeof message.summary === 'string') setSummary(message.summary); + if (Array.isArray(message.checks)) setChecks(message.checks as Check[]); + } else if (message.type === 'playing-codecs' && typeof message.codecs === 'string') { + setCodecs(message.codecs); + } + }} + /> + {sources && sources.length > 1 && ( +
+
+ Source +
+ {sources.map((option, index) => ( + + ))} +
+
+
+ )} + + ); +} diff --git a/theoplayer/examples/shared.module.css b/theoplayer/examples/shared.module.css index 02992e4810ea..2cdbe16feed2 100644 --- a/theoplayer/examples/shared.module.css +++ b/theoplayer/examples/shared.module.css @@ -413,3 +413,8 @@ width: 25%; } } + +.detectionChecks { + margin: 0.25rem 0 0; + padding-left: 1.25rem; +} diff --git a/theoplayer/examples/streaming/10-dolby-atmos.mdx b/theoplayer/examples/streaming/10-dolby-atmos.mdx new file mode 100644 index 000000000000..9547a3f145e4 --- /dev/null +++ b/theoplayer/examples/streaming/10-dolby-atmos.mdx @@ -0,0 +1,63 @@ +--- +sidebar_custom_props: { icon: 'πŸ”Š' } +description: Detect and play Dolby Atmos audio. +--- + +# Dolby Atmos + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/dolby-atmos/demo.html'; +import DetectionDemo from '../_components/DetectionDemo'; + + + +This example plays a Dolby Atmos (ec-3, 16/JOC) stream and probes the browser for Atmos support with +[`MediaCapabilities.decodingInfo`](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capabilities_API): +once for plain Dolby Digital Plus decoding, and once with `spatialRendering: true` for Atmos. +When `navigator.mediaCapabilities` is unavailable it falls back to `MediaSource.isTypeSupported`. + +```js +await navigator.mediaCapabilities.decodingInfo({ + type: 'media-source', + audio: { + contentType: 'audio/mp4; codecs="ec-3"', + channels: '16', + bitrate: 768000, + samplerate: 48000, + }, + spatialRendering: true, +}); +``` + +The status box above the player is green when both checks pass, yellow when the stream plays but +without Atmos spatial rendering, and red when the browser cannot decode ec-3 at all. + +:::note +Browsers cannot report whether the connected speakers or headphones are Atmos-capable β€” +the check only covers decoding, not the output device. +::: + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/examples/streaming/11-dolby-vision.mdx b/theoplayer/examples/streaming/11-dolby-vision.mdx new file mode 100644 index 000000000000..d8c22863885a --- /dev/null +++ b/theoplayer/examples/streaming/11-dolby-vision.mdx @@ -0,0 +1,62 @@ +--- +sidebar_custom_props: { icon: '🌈' } +description: Detect and play Dolby Vision video. +--- + +# Dolby Vision + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/dolby-vision/demo.html'; +import DetectionDemo from '../_components/DetectionDemo'; + + + +This example plays a Dolby Vision profile 8.4 stream (an HLG-compatible base layer with a Dolby Vision +enhancement, signaled via supplemental codecs: `dvhe.08.xx` for DASH and HLS). It probes the browser with +[`MediaCapabilities.decodingInfo`](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capabilities_API) +for the Dolby Vision codec and the HEVC Main10 HLG base layer, and checks for an HDR display with +`matchMedia('(dynamic-range: high)')`, re-checking when the display capability changes. + +```js +await navigator.mediaCapabilities.decodingInfo({ + type: 'media-source', + video: { + contentType: 'video/mp4; codecs="dvhe.08.09"', + bitrate: 18000000, + width: 3840, + height: 2160, + framerate: 60, + transferFunction: 'hlg', + }, +}); + +const hdrDisplay = matchMedia('(dynamic-range: high)').matches; +``` + +The status box is green when Dolby Vision decoding and an HDR display are both present, yellow when the +stream plays only as HLG or the display is not HDR, and red when the browser cannot decode the stream. + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/examples/streaming/12-hdr.mdx b/theoplayer/examples/streaming/12-hdr.mdx new file mode 100644 index 000000000000..a444e2889333 --- /dev/null +++ b/theoplayer/examples/streaming/12-hdr.mdx @@ -0,0 +1,45 @@ +--- +sidebar_custom_props: { icon: '✨' } +description: Detect and play HDR video. +--- + +# HDR + +import CodeBlock from '@theme/CodeBlock'; +import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/hdr/demo.html'; +import DetectionDemo from '../_components/DetectionDemo'; + + + +This example plays an HDR VP9 (profile 2, PQ / Rec. 2020) DASH stream and probes the browser with +[`MediaCapabilities.decodingInfo`](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capabilities_API) +for HDR decoding, plus `matchMedia('(dynamic-range: high)')` for an HDR display β€” re-checking when +the display capability changes. When `navigator.mediaCapabilities` is unavailable it falls back to +`MediaSource.isTypeSupported`. + +```js +await navigator.mediaCapabilities.decodingInfo({ + type: 'media-source', + video: { + contentType: 'video/mp4; codecs="vp09.02.40.10"', + bitrate: 8000000, + width: 1920, + height: 1080, + framerate: 30, + transferFunction: 'pq', + colorGamut: 'rec2020', + }, +}); + +const hdrDisplay = matchMedia('(dynamic-range: high)').matches; +``` + +The status box is green when the codec decodes and the display is HDR, yellow when the video decodes +but will be tone-mapped on a non-HDR display, and red when the browser cannot decode the stream. + +
+ Code + + {demoSource} + +
diff --git a/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html b/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html new file mode 100644 index 000000000000..054a38348164 --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html @@ -0,0 +1,108 @@ + + + + + Dolby Atmos + + + + + + + + + + + + + + + + diff --git a/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html b/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html new file mode 100644 index 000000000000..65ae9f8a5de1 --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html @@ -0,0 +1,126 @@ + + + + + Dolby Vision + + + + + + + + + + + + + + + + diff --git a/theoplayer/static/theoplayer/v11/examples/hdr/demo.html b/theoplayer/static/theoplayer/v11/examples/hdr/demo.html new file mode 100644 index 000000000000..264f72bcc851 --- /dev/null +++ b/theoplayer/static/theoplayer/v11/examples/hdr/demo.html @@ -0,0 +1,116 @@ + + + + + HDR + + + + + + + + + + + + + + + + From b00b8615a3faad51b6ac39567e69097a20de5f2b Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:17:42 +0000 Subject: [PATCH 07/19] Add a search bar to the examples overview Co-Authored-By: ceyhun.ozgoc --- .../SubcategoryDocCardList/index.tsx | 67 ++++++++++++++++--- .../SubcategoryDocCardList/styles.module.css | 12 ++++ theoplayer/examples/index.mdx | 2 +- 3 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 src/components/SubcategoryDocCardList/styles.module.css diff --git a/src/components/SubcategoryDocCardList/index.tsx b/src/components/SubcategoryDocCardList/index.tsx index dbf71b120427..3760cddb1244 100644 --- a/src/components/SubcategoryDocCardList/index.tsx +++ b/src/components/SubcategoryDocCardList/index.tsx @@ -1,24 +1,73 @@ -import { Fragment } from 'react'; +import { Fragment, useMemo, useState } from 'react'; import DocCardList, { type Props as DocCardListProps } from '@theme/DocCardList'; -import { useCurrentSidebarCategory } from '@docusaurus/plugin-content-docs/client'; +import { useCurrentSidebarCategory, useDocsVersion } from '@docusaurus/plugin-content-docs/client'; import { PropSidebarItem, PropSidebarItemCategory } from '@docusaurus/plugin-content-docs'; import Heading, { type HeadingType } from '@theme/Heading'; +import styles from './styles.module.css'; export interface Props extends Omit { headingLevel?: HeadingType; + searchable?: boolean; } function isCategory(item: PropSidebarItem): item is PropSidebarItemCategory { return item.type === 'category'; } -export default function SubcategoryDocCardList({ headingLevel, ...props }: Props) { +function itemText(item: PropSidebarItem, subcategoryLabel: string, description?: string): string { + const label = item.type === 'link' || item.type === 'category' ? item.label : ''; + return `${label} ${description ?? ''} ${subcategoryLabel}`.toLowerCase(); +} + +export default function SubcategoryDocCardList({ headingLevel, searchable = false, ...props }: Props) { const category = useCurrentSidebarCategory(); + const { docs } = useDocsVersion(); + const [query, setQuery] = useState(''); const subcategories = category.items.filter(isCategory); - return subcategories.map((subcategory) => ( - - {subcategory.label} - - - )); + + const filtered = useMemo(() => { + const terms = query.trim().toLowerCase().split(/\s+/).filter(Boolean); + if (terms.length === 0) return subcategories.map((subcategory) => ({ subcategory, items: subcategory.items })); + return subcategories + .map((subcategory) => ({ + subcategory, + items: subcategory.items.filter((item) => { + const haystack = + item.type === 'link' + ? itemText(item, subcategory.label, item.docId ? docs[item.docId]?.description : undefined) + : item.type === 'category' + ? `${item.label}`.toLowerCase() + : ''; + return terms.every((term) => haystack.includes(term)); + }), + })) + .filter(({ items }) => items.length > 0); + }, [query, subcategories, docs]); + + const noMatches = searchable && query.trim() !== '' && filtered.length === 0; + + return ( + <> + {searchable && ( + setQuery(event.target.value)} + onKeyDown={(event) => { + if (event.key === 'Escape') setQuery(''); + }} + /> + )} + {noMatches &&

No examples match β€œ{query.trim()}”.

} + {filtered.map(({ subcategory, items }) => ( + + {subcategory.label} + + + ))} + + ); } diff --git a/src/components/SubcategoryDocCardList/styles.module.css b/src/components/SubcategoryDocCardList/styles.module.css new file mode 100644 index 000000000000..c5bee95164c2 --- /dev/null +++ b/src/components/SubcategoryDocCardList/styles.module.css @@ -0,0 +1,12 @@ +.searchInput { + display: block; + width: 100%; + max-width: 32rem; + margin-bottom: 1.5rem; + padding: 0.5rem 0.75rem; + font: inherit; + color: var(--ifm-font-color-base); + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: var(--ifm-global-radius); +} diff --git a/theoplayer/examples/index.mdx b/theoplayer/examples/index.mdx index 3779fa4807b6..32c315c4f17f 100644 --- a/theoplayer/examples/index.mdx +++ b/theoplayer/examples/index.mdx @@ -11,4 +11,4 @@ See the player in action! import SubcategoryDocCardList from '@site/src/components/SubcategoryDocCardList'; - + From 03c7b4079add181a9bf2428f10c3b97387f4aaaa Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:34:14 +0000 Subject: [PATCH 08/19] Fix audio-only example iframe height, poster and idle hiding Co-Authored-By: ceyhun.ozgoc --- theoplayer/examples/ui/07-audio-only.mdx | 14 +++++++------- .../theoplayer/v11/examples/audio-only/demo.html | 9 +++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/theoplayer/examples/ui/07-audio-only.mdx b/theoplayer/examples/ui/07-audio-only.mdx index 2036df2a5828..3d234e198cb7 100644 --- a/theoplayer/examples/ui/07-audio-only.mdx +++ b/theoplayer/examples/ui/07-audio-only.mdx @@ -10,7 +10,7 @@ import demoSource from '!!raw-loader!../../static/theoplayer/v11/examples/audio- import useBaseUrl from '@docusaurus/useBaseUrl'; import Example from '@site/src/components/Example'; - + With Open Video UI you compose a player from only the controls you need. This example uses a bare `` element with a track info area in the top chrome and a control bar containing just @@ -24,14 +24,14 @@ theoplayer-ui { --theoplayer-aspect-ratio: none; --theoplayer-video-height: 0; --theoplayer-video-width: 0; - --theoplayer-height: auto; + --theoplayer-height: 6.5rem; } ``` ```html - -
...
- + +
...
+ @@ -41,8 +41,8 @@ theoplayer-ui {
``` -`user-idle-timeout="-1"` disables the idle timer and `no-auto-hide` on the controls keeps them -visible at all times, since there is no video to tap when the controls fade out. +`no-auto-hide` on the controls keeps them visible at all times instead of letting them +fade out when the player is idle, since there is no video to tap when the controls fade out.
Code diff --git a/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html b/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html index 424235a1f216..929d22d34ced 100644 --- a/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html +++ b/theoplayer/static/theoplayer/v11/examples/audio-only/demo.html @@ -20,6 +20,7 @@ } theoplayer-ui { + display: block; width: 100%; /* Collapse the video area: this player renders audio controls only. */ --theoplayer-aspect-ratio: none; @@ -76,18 +77,18 @@ licenseUrl: Point this to your license file, or replace it with a license property. - user-idle-timeout="-1": keep the controls visible instead of auto-hiding them. + no-auto-hide on the controls: keep them visible instead of letting them + fade out when the player is idle. -->
- +
Elephants Dream
-
Open Movie Project · Soundtrack
+
Blender Foundation
From 7b50babafd6364c4cbd8773ce0e2729df25bfe63 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:34:14 +0000 Subject: [PATCH 09/19] Move spatialRendering into the audio configuration Co-Authored-By: ceyhun.ozgoc --- theoplayer/examples/streaming/10-dolby-atmos.mdx | 2 +- .../static/theoplayer/v11/examples/dolby-atmos/demo.html | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/theoplayer/examples/streaming/10-dolby-atmos.mdx b/theoplayer/examples/streaming/10-dolby-atmos.mdx index 9547a3f145e4..4ee90bd2fe26 100644 --- a/theoplayer/examples/streaming/10-dolby-atmos.mdx +++ b/theoplayer/examples/streaming/10-dolby-atmos.mdx @@ -42,8 +42,8 @@ await navigator.mediaCapabilities.decodingInfo({ channels: '16', bitrate: 768000, samplerate: 48000, + spatialRendering: true, }, - spatialRendering: true, }); ``` diff --git a/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html b/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html index 054a38348164..745f44fcd81a 100644 --- a/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html +++ b/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html @@ -45,12 +45,10 @@ - - - - - - - - - - From a1eb06a91caa2fa9d1cd49bdef06831a988fe1cf Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 11:54:12 +0000 Subject: [PATCH 13/19] Fix detection summaries and the THEOlive readout sentence Co-Authored-By: ceyhun.ozgoc --- theoplayer/examples/streaming/09-theolive.mdx | 2 +- theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html | 2 +- .../static/theoplayer/v11/examples/dolby-vision/demo.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/theoplayer/examples/streaming/09-theolive.mdx b/theoplayer/examples/streaming/09-theolive.mdx index ac5abf76bdd6..1efac07949bf 100644 --- a/theoplayer/examples/streaming/09-theolive.mdx +++ b/theoplayer/examples/streaming/09-theolive.mdx @@ -23,7 +23,7 @@ player.source = { }; ``` -The readout below the player shows `player.latency.currentLatency`, the end-to-end latency in seconds, +The readout above shows `player.latency.currentLatency`, the end-to-end latency in seconds, updated on every `timeupdate` event. See the [`TheoLiveSource`](pathname:///theoplayer/v11/api-reference/web/interfaces/TheoLiveSource.html) API reference for all available fields. diff --git a/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html b/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html index 745f44fcd81a..140fa42d7d27 100644 --- a/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html +++ b/theoplayer/static/theoplayer/v11/examples/dolby-atmos/demo.html @@ -86,7 +86,7 @@ ? 'Dolby Atmos is supported on this device.' : level === 'warning' ? 'Dolby Digital Plus plays, but without Atmos spatial rendering.' - : 'This browser cannot decode ec-3 audio β€” the stream will not play here.'; + : 'This browser cannot decode Dolby Digital Plus (ec-3) audio.'; sendToParent('detection-status', { level, summary, checks }); player.videoTracks.addEventListener('addtrack', (event) => diff --git a/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html b/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html index 5d58178e9d0d..89387e912d23 100644 --- a/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html +++ b/theoplayer/static/theoplayer/v11/examples/dolby-vision/demo.html @@ -121,7 +121,7 @@ level === 'success' ? 'Dolby Vision is supported on this device and display.' : level === 'danger' - ? 'This browser cannot decode HEVC β€” the stream will not play here.' + ? 'This browser cannot decode HEVC video.' : dv.status !== 'supported' ? 'HEVC HLG plays here, but without Dolby Vision.' : 'Dolby Vision decodes, but this display is not HDR.'; From feb6c93b3013aa58c02136806867b09ba5d022a6 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 11:54:12 +0000 Subject: [PATCH 14/19] Remove the HDR example Co-Authored-By: ceyhun.ozgoc --- spellcheck/dictionary.txt | 1 - .../theoplayer/v11/examples/conviva/demo.html | 139 +++++++++++------- 2 files changed, 82 insertions(+), 58 deletions(-) diff --git a/spellcheck/dictionary.txt b/spellcheck/dictionary.txt index 15472243d513..a7d63598f188 100644 --- a/spellcheck/dictionary.txt +++ b/spellcheck/dictionary.txt @@ -1023,5 +1023,4 @@ Youbora Zettabyte HLG HLG-compatible -PQ UIs diff --git a/theoplayer/static/theoplayer/v11/examples/conviva/demo.html b/theoplayer/static/theoplayer/v11/examples/conviva/demo.html index 1410fd182f1c..446994775630 100644 --- a/theoplayer/static/theoplayer/v11/examples/conviva/demo.html +++ b/theoplayer/static/theoplayer/v11/examples/conviva/demo.html @@ -46,20 +46,18 @@ > From 5e8127bb8c5e60561b11d088e5e934c82327265f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 11:54:12 +0000 Subject: [PATCH 15/19] Add credential inputs and a detailed event log to the Conviva example Co-Authored-By: ceyhun.ozgoc --- .../examples/_components/ConvivaDemo.tsx | 87 +++++++++++++------ theoplayer/examples/analytics/01-conviva.mdx | 19 ++-- 2 files changed, 74 insertions(+), 32 deletions(-) diff --git a/theoplayer/examples/_components/ConvivaDemo.tsx b/theoplayer/examples/_components/ConvivaDemo.tsx index 01024bf80676..ddffa0893c3f 100644 --- a/theoplayer/examples/_components/ConvivaDemo.tsx +++ b/theoplayer/examples/_components/ConvivaDemo.tsx @@ -1,4 +1,4 @@ -import React, { type JSX, useRef, useState } from 'react'; +import React, { type JSX, useEffect, useRef, useState } from 'react'; import useBaseUrl from '@docusaurus/useBaseUrl'; import Example, { type ExampleController } from '@site/src/components/Example'; import styles from '../shared.module.css'; @@ -11,7 +11,7 @@ interface StreamTemplate { source: { sources: { src: string; type: string }; poster?: string; - metadata: { title: string }; + metadata: { title: string; subtitle: string }; }; } @@ -21,6 +21,9 @@ interface EventEntry { details: string; } +const DEFAULT_CUSTOMER_KEY = '876a2328cc34e791190d855daf389567c96d1e86'; +const DEFAULT_GATEWAY_URL = `https://${DEFAULT_CUSTOMER_KEY}.ts-testonly.conviva.com`; + const templates: StreamTemplate[] = [ { id: 'hls-vod', @@ -30,7 +33,7 @@ const templates: StreamTemplate[] = [ source: { sources: { src: 'https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_corrected.m3u8', type: 'application/x-mpegurl' }, poster: 'https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg', - metadata: { title: 'Big Buck Bunny' }, + metadata: { title: 'Big Buck Bunny', subtitle: 'HLS β€’ VOD' }, }, }, { @@ -40,7 +43,7 @@ const templates: StreamTemplate[] = [ streamType: 'LIVE', source: { sources: { src: 'https://demo.unified-streaming.com/k8s/live/stable/live.isml/.m3u8', type: 'application/x-mpegurl' }, - metadata: { title: 'Live stream' }, + metadata: { title: 'Live stream', subtitle: 'HLS β€’ LIVE' }, }, }, { @@ -51,7 +54,7 @@ const templates: StreamTemplate[] = [ source: { sources: { src: 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd', type: 'application/dash+xml' }, poster: 'https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg', - metadata: { title: 'Big Buck Bunny' }, + metadata: { title: 'Big Buck Bunny', subtitle: 'DASH β€’ VOD' }, }, }, { @@ -61,24 +64,34 @@ const templates: StreamTemplate[] = [ streamType: 'LIVE', source: { sources: { src: 'https://demo.unified-streaming.com/k8s/live/stable/live.isml/.mpd', type: 'application/dash+xml' }, - metadata: { title: 'Live stream' }, + metadata: { title: 'Live stream', subtitle: 'DASH β€’ LIVE' }, }, }, ]; export default function ConvivaDemo(): JSX.Element { const exampleRef = useRef(null); + const logRef = useRef(null); const [templateId, setTemplateId] = useState(templates[0].id); + const [customerKey, setCustomerKey] = useState(''); + const [gatewayUrl, setGatewayUrl] = useState(''); const [events, setEvents] = useState([]); - function selectTemplate(id: string): void { - setTemplateId(id); - const template = templates.find((entry) => entry.id === id); + useEffect(() => { + if (logRef.current) { + logRef.current.scrollTop = logRef.current.scrollHeight; + } + }, [events]); + + function loadStream(): void { + const template = templates.find((entry) => entry.id === templateId); if (!template) return; - setEvents([]); exampleRef.current?.postMessage({ - type: 'load-source', - stream: { assetName: template.assetName, streamType: template.streamType, source: template.source }, + type: 'load-stream', + template: { assetName: template.assetName, streamType: template.streamType, source: template.source }, + // An empty input falls back to its placeholder value. + customerKey: customerKey.trim() || DEFAULT_CUSTOMER_KEY, + gatewayUrl: gatewayUrl.trim() || DEFAULT_GATEWAY_URL, }); } @@ -95,21 +108,41 @@ export default function ConvivaDemo(): JSX.Element { />
- Stream templates -
- {templates.map((template) => ( - - ))} -
+ + + +
-
+
{events.length === 0 ? ( No events reported yet. ) : ( @@ -117,7 +150,7 @@ export default function ConvivaDemo(): JSX.Element {
{entry.time} {entry.event} - {entry.details || 'β€”'} + {entry.details}
)) )} diff --git a/theoplayer/examples/analytics/01-conviva.mdx b/theoplayer/examples/analytics/01-conviva.mdx index 83296cffa84d..a7b6a6132571 100644 --- a/theoplayer/examples/analytics/01-conviva.mdx +++ b/theoplayer/examples/analytics/01-conviva.mdx @@ -12,12 +12,18 @@ import ConvivaDemo from '../_components/ConvivaDemo'; This example reports playback to [Conviva](https://pulse.conviva.com/) using the -[Conviva connector for THEOplayer](https://www.npmjs.com/package/@theoplayer/conviva-connector-web). +[Conviva connector for THEOplayer](https://www.npmjs.com/package/@theoplayer/conviva-connector-web) +([API reference](https://theoplayer.github.io/web-connectors/api/modules/Conviva_Connector.html)). The connector bridges player events to the Conviva SDK: it starts a session when playback begins and reports content metadata, buffering and errors automatically. +The connector must be created before any source is set on the player. ```js -const convivaIntegration = new THEOplayerConvivaConnector.ConvivaConnector(player, convivaMetadata, convivaConfig); +const convivaIntegration = new THEOplayerConvivaConnector.ConvivaConnector(player, convivaMetadata, { + debug: true, + customerKey, + gatewayUrl, +}); // Source-specific metadata does not carry over to the next source, // so set it again after every sourcechange. @@ -30,9 +36,12 @@ player.addEventListener('sourcechange', () => { }); ``` -The `convivaConfig` in this demo uses a Conviva test customer key and Touchstone gateway URL β€” -replace them with your own credentials (and omit `gatewayUrl` for production). -Use the stream templates to switch between HLS/DASH and VOD/live sources; the metadata is updated on each `sourcechange`. +The Customer key and Gateway URL inputs accept your own credentials; an empty input falls back to +the demo's test values (omit `gatewayUrl` for production). Pressing **Load stream** calls +`convivaIntegration.destroy()` to close the previous session, creates a new `ConvivaConnector` +with the entered credentials, and then sets the selected source. +Use the stream templates to switch between HLS/DASH and VOD/live sources; the content metadata is +updated on each `sourcechange`. :::note With `debug: true`, Conviva SDK debug logs are printed in the browser's DevTools console. From 63f67f5f9dd44bed2b7bb581e5e7d5c276129259 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 12:08:48 +0000 Subject: [PATCH 16/19] Fix Conviva panel layout, event log columns and iframe scrollbars Co-Authored-By: ceyhun.ozgoc --- .../examples/_components/ConvivaDemo.tsx | 4 +-- theoplayer/examples/shared.module.css | 25 ++++++++++++++++--- .../v11/examples/audio-only/demo.html | 7 ++++++ .../theoplayer/v11/examples/conviva/demo.html | 1 + 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/theoplayer/examples/_components/ConvivaDemo.tsx b/theoplayer/examples/_components/ConvivaDemo.tsx index ddffa0893c3f..67605a5851a9 100644 --- a/theoplayer/examples/_components/ConvivaDemo.tsx +++ b/theoplayer/examples/_components/ConvivaDemo.tsx @@ -107,7 +107,7 @@ export default function ConvivaDemo(): JSX.Element { }} />
-
+
- - + + + +
+
+
diff --git a/theoplayer/static/theoplayer/v11/examples/millicast/demo.html b/theoplayer/static/theoplayer/v11/examples/millicast/demo.html index f48beb02d7a7..756e611e3f0b 100644 --- a/theoplayer/static/theoplayer/v11/examples/millicast/demo.html +++ b/theoplayer/static/theoplayer/v11/examples/millicast/demo.html @@ -2,7 +2,7 @@ - Millicast + OptiView Real-time Streaming @@ -37,7 +37,7 @@ licenseUrl: Point this to your license file, or replace it with a license property. - A Millicast live source: 'src' is the stream name, 'streamAccountId' the account. + An OptiView Real-time Streaming live source: 'src' is the stream name, 'streamAccountId' the account. Secure streams also need a 'subscriberToken'. --> - THEOlive + OptiView Live Streaming @@ -37,7 +37,7 @@ licenseUrl: Point this to your license file, or replace it with a license property. - A THEOlive source: 'src' is the channel or distribution ID. + An OptiView Live Streaming source: 'src' is the channel or distribution ID. -->