Skip to content

Commit

Permalink
Merge pull request #1240 from canalplus/feat/representationListUpdate…
Browse files Browse the repository at this point in the history
…-event

Add `representationListUpdate` event for the v4
  • Loading branch information
peaBerberian committed Sep 26, 2023
2 parents 0a4298d + a20f949 commit eccbcf3
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
61 changes: 61 additions & 0 deletions doc/api/Player_Events.md
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,67 @@ The payload for this event is an object with the following properties:
application's logic.


<div class="warning">
This event is not sent in <i>DirectFile</i> mode (see
<a href="./Loading_a_Content.md#transport">transport option</a>)
</div>

### representationListUpdate

_payload type_: `Object`

Event triggered if the list of available [`Representation`](../Getting_Started/Glossary.md#representation)
linked to the currently-chosen video, audio or text track for any
[Period](../Getting_Started/Glossary.md#period) (for example inspectable
through the `representations` property of audio and video track objects) may
have changed compared to what it was before.

Note that you won't receive a `representationListUpdate` event the initial time
the corresponding track is selected, it is only sent when its linked list of
available `Representation`s might have dynamically changed during playback.
For now, this may only happen if at least one of the Representation in the
chosen track became undecipherable (in which case it is not available anymore)
or decipherable (in which case it becomes available again).

The main point of this event is to let you adjust your tracks and
Representations choice when they depend on the list of available Representation.

The payload for this event is an object with the following properties:

- `trackType` (`string`): The type of track concerned. Can for example be
`audio` for an audio track, `video` for a video track or `text` for a text
track.

- `period` (`Object`): Information about the concerned
[Period](../Getting_Started/Glossary.md#period). This object contains as
properties:

- `start` (`number`): The starting position at which the Period starts, in
seconds.

- `end` (`number|undefined`): The position at which the Period ends, in
seconds.

`undefined` either if not known or if the Period has no end yet (e.g. for
live contents, the end might not be known for now).

- `id` (`string`): `id` of the Period, allowing to call track and
Representation selection APIs (such as `setAudioTrack` and
`lockVideoRepresentations` for example) even when the Period changes.

- `reason` (`string`): The reason for the update.
For now, it can be set to:

- `"decipherability-update"`: The list of available `Representation`s is
being updated either because at least one of that track's
`Representation` became undecipherable or because it became decipherable
again.

Though other reasons may be added in the future (for future reasons not
covered by those values), so you should expect this possibility in your
application's logic.


<div class="warning">
This event is not sent in <i>DirectFile</i> mode (see
<a href="./Loading_a_Content.md#transport">transport option</a>)
Expand Down
58 changes: 58 additions & 0 deletions src/core/api/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
ILockedAudioRepresentationsSettings,
ILockedVideoRepresentationsSettings,
ITrackUpdateEventPayload,
IRepresentationListUpdateContext,
IPeriod,
IPeriodChangeEvent,
IPlayerError,
Expand All @@ -70,7 +71,9 @@ import {
IVideoTrack,
IVideoTrackSetting,
IVideoTrackSwitchingMode,
ITrackType,
} from "../../public_types";
import arrayFind from "../../utils/array_find";
import arrayIncludes from "../../utils/array_includes";
import assert from "../../utils/assert";
import assertUnreachable from "../../utils/assert_unreachable";
Expand Down Expand Up @@ -2162,6 +2165,60 @@ class Player extends EventEmitter<IPublicAPIEvent> {
return;
}
}, contentInfos.currentContentCanceller.signal);

manifest.addEventListener("decipherabilityUpdate", (elts) => {
/**
* Array of tuples only including once the Period/Track combination, and
* only when it concerns the currently-selected track.
*/
const periodsAndTrackTypes = elts.reduce(
(acc: Array<[Period, ITrackType]>, elt) => {
const isFound = arrayFind(
acc,
(x) => x[0].id === elt.period.id &&
x[1] === elt.adaptation.type
) === undefined;

if (!isFound) {
// Only consider the currently-selected tracks.
// NOTE: Maybe there's room for optimizations? Unclear.
const { tracksStore } = contentInfos;
if (tracksStore === null) {
return acc;
}
let isCurrent = false;
const periodRef = tracksStore.getPeriodObjectFromPeriod(elt.period);
if (periodRef === undefined) {
return acc;
}
switch (elt.adaptation.type) {
case "audio":
isCurrent = tracksStore
.getChosenAudioTrack(periodRef)?.id === elt.adaptation.id;
break;
case "video":
isCurrent = tracksStore
.getChosenVideoTrack(periodRef)?.id === elt.adaptation.id;
break;
case "text":
isCurrent = tracksStore
.getChosenTextTrack(periodRef)?.id === elt.adaptation.id;
break;
}
if (isCurrent) {
acc.push([elt.period, elt.adaptation.type]);
}
}
return acc;
}, []);
for (const [period, trackType] of periodsAndTrackTypes) {
this._priv_triggerEventIfNotStopped(
"representationListUpdate",
{ period, trackType, reason: "decipherability-update" },
contentInfos.currentContentCanceller.signal
);
}
}, contentInfos.currentContentCanceller.signal);
}

/**
Expand Down Expand Up @@ -2654,6 +2711,7 @@ interface IPublicAPIEvent {
newAvailablePeriods : IPeriod[];
brokenRepresentationsLock : IBrokenRepresentationsLockContext;
trackUpdate : ITrackUpdateEventPayload;
representationListUpdate : IRepresentationListUpdateContext;
seeking : null;
seeked : null;
streamEvent : IStreamEvent;
Expand Down
7 changes: 7 additions & 0 deletions src/public_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,13 @@ export interface ITrackUpdateEventPayload {
string;
}

export interface IRepresentationListUpdateContext {
period : IPeriod;
trackType : ITrackType;
reason : "decipherability-update" |
string;
}

export interface ILockedVideoRepresentationsSettings {
representations : string[];
periodId? : string | undefined;
Expand Down

0 comments on commit eccbcf3

Please sign in to comment.