Skip to content

Commit

Permalink
Implement Common Media Client Data on the RxPlayer
Browse files Browse the repository at this point in the history
  • Loading branch information
peaBerberian committed Jun 18, 2024
1 parent 2b8dcfd commit 9c097d3
Show file tree
Hide file tree
Showing 41 changed files with 1,400 additions and 133 deletions.
41 changes: 41 additions & 0 deletions demo/full/scripts/components/Options/RequestConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from "react";
import Checkbox from "../CheckBox";
import DEFAULT_VALUES from "../../lib/defaultOptionsValues";
import PlayerOptionNumberInput from "./PlayerOptionNumberInput";
import Select from "../Select";

const { Fragment, useCallback, useEffect, useState } = React;

Expand All @@ -19,19 +20,23 @@ const DEFAULT_MANIFEST_REQUEST_TIMEOUT =
function RequestConfig({
manifestRequestTimeout,
manifestRetry,
cmcdCommunicationMethod,
onManifestRequestTimeoutChange,
onManifestRetryChange,
onSegmentRequestTimeoutChange,
onSegmentRetryChange,
onCmcdChange,
segmentRequestTimeout,
segmentRetry,
}: {
manifestRequestTimeout: number;
manifestRetry: number;
cmcdCommunicationMethod: string;
onManifestRequestTimeoutChange: (val: number) => void;
onManifestRetryChange: (val: number) => void;
onSegmentRequestTimeoutChange: (val: number) => void;
onSegmentRetryChange: (val: number) => void;
onCmcdChange: (val: string) => void;
segmentRequestTimeout: number;
segmentRetry: number;
}): JSX.Element {
Expand Down Expand Up @@ -76,6 +81,27 @@ function RequestConfig({
manifestRequestTimeout !== -1,
);

let cmcdDescMsg;
switch (cmcdCommunicationMethod) {
case "disabled":
cmcdDescMsg = "Not relying on CMCD with the CDN";
break;
case "query":
cmcdDescMsg = "Communicate CMCD payload through URL's query strings";
break;
case "headers":
cmcdDescMsg = "Communicate CMCD payload through HTTP(S) headers";
break;
default:
cmcdDescMsg = "Unknown value";
break;
}

const onCmcdSelection = React.useCallback(
({ value }: { value: string }) => onCmcdChange(value),
[onCmcdChange],
);

// Update manifestRequestTimeout when its linked text change
useEffect(() => {
// Note that this unnecessarily also run on first render - there seem to be
Expand Down Expand Up @@ -275,6 +301,21 @@ function RequestConfig({
: `Stop manifest requests after ${manifestRequestTimeout} millisecond(s)`}
</span>
</li>

<li className="featureWrapperWithSelectMode">
<Select
ariaLabel="Selecting the CMCD communication method"
disabled={false}
className="playerOptionInput"
name="cmcd"
onChange={onCmcdSelection}
selected={{ value: cmcdCommunicationMethod, index: undefined }}
options={["disabled", "query", "headers"]}
>
CMCD (Common Media Client Data) communication type
</Select>
<span className="option-desc">{cmcdDescMsg}</span>
</li>
</Fragment>
);
}
Expand Down
34 changes: 33 additions & 1 deletion demo/full/scripts/controllers/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import type {
IConstructorSettings,
ILoadVideoSettings,
} from "../lib/defaultOptionsValues";
import {
import type {
IAudioRepresentationsSwitchingMode,
ICmcdOptions,
IVideoRepresentationsSwitchingMode,
} from "../../../../src/public_types";

Expand Down Expand Up @@ -61,11 +62,13 @@ function Settings({
} = playerOptions;
const {
autoPlay,
cmcd,
defaultAudioTrackSwitchingMode,
enableFastSwitching,
requestConfig,
onCodecSwitch,
} = loadVideoOptions;
const cmcdCommunicationMethod = cmcd?.communicationType ?? "disabled";
const { manifest: manifestRequestConfig, segment: segmentRequestConfig } =
requestConfig;
const { maxRetry: segmentRetry, timeout: segmentRequestTimeout } = segmentRequestConfig;
Expand All @@ -91,6 +94,33 @@ function Settings({
[updateTryRelyOnWorker],
);

const onCmcdChange = useCallback(
(value: string) => {
updateLoadVideoOptions((prevOptions) => {
let newCmcdType: ICmcdOptions["communicationType"] | undefined;
if (value === "query") {
newCmcdType = "query";
} else if (value === "headers") {
newCmcdType = "headers";
} else {
newCmcdType = undefined;
}
if (newCmcdType === prevOptions.cmcd?.communicationType) {
return prevOptions;
}
return Object.assign({}, prevOptions, {
cmcd:
newCmcdType === undefined
? undefined
: {
communicationType: newCmcdType,
},
});
});
},
[updateLoadVideoOptions],
);

const onVideoResolutionLimitChange = useCallback(
(videoResolutionLimitArg: { value: string }) => {
updatePlayerOptions((prevOptions) => {
Expand Down Expand Up @@ -346,10 +376,12 @@ function Settings({
segmentRetry={segmentRetry}
segmentRequestTimeout={segmentRequestTimeout}
manifestRetry={manifestRetry}
cmcdCommunicationMethod={cmcdCommunicationMethod}
onSegmentRetryChange={onSegmentRetryChange}
onSegmentRequestTimeoutChange={onSegmentRequestTimeoutChange}
onManifestRetryChange={onManifestRetryChange}
onManifestRequestTimeoutChange={onManifestRequestTimeoutChange}
onCmcdChange={onCmcdChange}
/>
</Option>
<Option title="Track Switch Mode">
Expand Down
2 changes: 2 additions & 0 deletions demo/full/scripts/lib/defaultOptionsValues.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
ICmcdOptions,
IConstructorOptions,
ILoadVideoOptions,
} from "../../../../src/public_types";
Expand All @@ -14,6 +15,7 @@ const defaultOptionsValues = {
},
loadVideo: {
autoPlay: true,
cmcd: undefined as ICmcdOptions | undefined,
defaultAudioTrackSwitchingMode: "reload",
enableFastSwitching: true,
requestConfig: {
Expand Down
35 changes: 35 additions & 0 deletions doc/api/Loading_a_Content.md
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,41 @@ If not set or set to `"auto"`, you can see which mode is effective by calling th
If the `useWorker` property is set to `false`, you're running in `"main"` mode, if set to
`true`, you're running in `"multithread"` mode.

### cmcd

_type_: `Object|undefined`

_defaults_: `"undefined"`

<div class="warning">
This option has no effect in <i>DirectFile</i> mode (see <a href="#transport">
transport option</a>)
</div>

When set to an object, it enables "Common Media Client Data" (CMCD) so the RxPlayer is
able to report playback conditions to the CDN.

If set to `undefined` or not defined, CMCD will be disabled.

When set to an Object, it can have the following properties:

- `contentId` (`string|undefined`): Content ID delivered by CMCD metadata for that
content. If not specified, a default one will be generated.

It is heavily recommended that you provide your own content identifier here.

- `sessionId` (`string|undefined`): Session ID delivered by CMCD metadata. If not
specified, a default one will be generated.

- `communicationType` (`string|undefined`): Way in which the CMCD metadata is
communicated.

Can be set to `"query"` for communicating it through query strings or `"headers"` for
communicating it through headers (which may lead to supplementary complexities linked to
CORS policies such as preflight request, blocking etc.).

If not set, the RxPlayer will automatically select the most appropriate way instead.

### checkMediaSegmentIntegrity

_type_: `Function|undefined`
Expand Down
43 changes: 23 additions & 20 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ it:
| |
+---------------------------------------------+
|
| call RxPlayer API
| call the RxPlayer API
|
-------------------------|- RxPlayer Main Thread ---------------------------
|
Expand All @@ -52,29 +52,32 @@ it:
|(./main_thread/init)| creates | Text Displayer |
| | --------------------------->|(./main_thread/te |
+--------------------+ |xt_displayer) |
| ^ +------------------+
| | Message exchanges ^
| | |
--------|--|------ RxPlayer Core (May run in a WebWorker) --------------|---
v | |
| ^ +------------------+
| | Message exchanges ^
| | |
---|--|----------- RxPlayer Core (May run in a WebWorker) ---------|---
| | |
| | (*Only if running in a WebWorker)
| | Exchange messages with the main
V | thread and process them.
+---------------------------+ +----------------------------+ |
| | creates | | |
| Worker Main* |-------->| Manifest Fetcher | |
| (./core/main/worker) | | (./core/fetchers/manifest) | |
| | | | |
+---------------------------+ +----------------------------+ |
(*Only if running in a | Load and | |
WebWorker) | refresh the | Ask to load |
Exchange messages with | Manifest | and parse the |
the main thread and | | Manifest |
process them. | v |
| +--------------------+ | ` Internet
| | | request | ` ,,,,,
| | transport |--------------+---`-->( CDN )
creates | | (./core/transport) | | ` `````
| | |<---+ | `
| +--------------------+ \ |
| Abstract the streaming \ |
| Creates | Load and | |
V | refresh the | Ask to load |
+-------------------+ | Manifest | and parse the |
| | | creates | Manifest |
| CMCD data builder | | v |
| (./core/cmcd) | | +--------------------+ | ` Internet
| | | | | request | ` ,,,,,
+-------------------+ | | transport |--------------+---`-->( CDN )
Perform data collection | | (./transport) | | ` `````
for the "Common Media | | |<---+ | `
Client Data" (CMCD) | +--------------------+ \ |
scheme. | Abstract the streaming \ |
| protocol (e.g. DASH) \ |
| \ |
Stream (./core/stream) | \ |
Expand Down Expand Up @@ -248,10 +251,10 @@ The previous schema mostly illustrated the most complex code path of the three (
`DirectfileContentInitializer` is called by the API to start-up such contents and a
specialized `MediaElementTracksStore` is handling tracks specifically for directfile
contents (as they are handled differently than for other code paths, here trough API
exposed by the browser)have .
exposed by the browser).

2. A second code path, we may call the "monothreaded code path" apply for non-directfile
contents (so, contents which rely on MSE API instead) loaded in monothreaded mode,
contents (so, contents which rely on the MSE API instead) loaded in monothreaded mode,
which is the default.

It is much closer to the schema of the previous chapter:
Expand Down
5 changes: 5 additions & 0 deletions src/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ Those modules are:
Link the `transports` module with the rest of the code, to download segments,
download/refresh the manifest and collect data (such as the user's bandwidth) for the
other modules.

- **the `CmcdDataBuilder` (./cmcd)**

Perform data collection and retrieval for the "Common Media Client Data" scheme, which
is a specification allowing to communicate about playback conditions with a CDN.
Loading

0 comments on commit 9c097d3

Please sign in to comment.