Skip to content

Commit

Permalink
[Proposal] DRM: Add keySystems[].renewMediaKeys loadVideo option
Browse files Browse the repository at this point in the history
We've seen multiple occurences lately on several devices where playback
failed after playing a few encrypted contents.

On those, setting the `closesSessionsOnStop` option (an option and
already-existing work-around) had no effect, yet renewing the MediaKeys
at each load fixed the issue.

It's very probably a device bug. For those, we usually had the strategy
of knowing on which devices this problem was encountered, detect it
inside the RxPlayer, and choose to always renew the `MediaKeys` on those
(without the application even knowing we did that).

However, some users suggested to us to add this as an option, because
they may have reproduced the issue on other devices.

I'm kind of ambivalent toward adding this as an option:

  - I generally prefer our strategy of fixing it for all devices with the
    issue, with people reporting issues to us when a new device has the
    issue. This allows to fix it once and for all for all those devices.

  - I understand that some applications might prefer to iterate rapidly
    and be able to have more control over the RxPlayer behavior.

Another PR, #1510, would allow doing this by patching our config instead
but this would not be doable in production for applications (config
properties are not something we guarantee in our API).

This PR however, would allow applications to do it when and wherever they
please.

Thoughts?
  • Loading branch information
peaBerberian committed Sep 4, 2024
1 parent 683b02e commit 3fdedf5
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 11 deletions.
54 changes: 46 additions & 8 deletions doc/api/Decryption_Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,17 +237,55 @@ The `maxSessionCacheSize` option allows to configure the maximum number of

_type_: `Boolean | undefined`

If set to `true`, the `MediaKeySession` created for a content will be immediately closed
when the content stops its playback.
If set to `true`, all open `MediaKeySession` (JavaScript Objects linked to the keys used
to decrypt the content) will be closed when the current playback stops.

This might be required by your key system implementation (most often, it is not).
By default, we keep created `MediaKeySession` from previous contents (up to
[`maxSessionCacheSize`](#maxsessioncachesize) `MediaKeySession`) to speed-up playback and
avoid round-trips to the license server if the user ever decide to go back to those
contents or to other contents relying to the same keys.

If set to `false` or not set, the `MediaKeySession` can be reused if the same content
needs to be re-decrypted.
However we found that some devices poorly handle that optimization.

If you want to set this property because the current device has a limited number of
`MediaKeySession` that can be created at the same time, prefer using `maxSessionCacheSize`
instead.
Note that if setting that property to `true` fixes your issue, it may be that it's just
the [`maxSessionCacheSize`](#maxsessioncachesize) which is for now too high.

However if your problem doesn't disappear after setting `closeSessionsOnStop` to `true`,
you may try [`renewMediaKeys`](#renewmediakeys) next.

### renewMediaKeys

If `true`, we will create a new `MediaKeys` instance (a JavaScript object needed to
decrypt contents) if needed for that content.

If `false` or if not set, we might rely on the previous `MediaKeys` if a compatible one is
already set on the media element, allowing to potentailly speed-up content playback.

We noticed that reusing a previous MediaKeys had led to errors on a few devices. For
example some smart TVs had shown errors after playing several encrypted contents, errors
which disappeared if we "renewed" the `MediaKeys` for each content.

We should already be able to detect most of those cases in the RxPlayer logic. However, it
is still possible that we don't know yet of a device which also has problem with that
optimization.

If you have issues appearing only after playing multiple encrypted contents:

- First, try setting the `closeSessionsOnStop` option which is less destructive.

If it fixes your issue, it may be that it's just the number of `MediaKeySession` cached
by the RxPlayer that is here too high.

In that case you can instead update the `maxSessionCacheSize` option to still profit
from a `MediaKeySession` cache (which avoid making license requests for already-played
contents).

If that second option doesn't seem to have an effect, you can just set
`closeSessionsOnStop`.

- If none of the precedent work-arounds work however, you can try setting `renewMediaKeys`
to `true`. If it fixes your problem, please open an RxPlayer issue so we can add your
device to our list.

### singleLicensePer

Expand Down
1 change: 1 addition & 0 deletions src/main_thread/decrypt/get_media_keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export default async function getMediaKeysInfos(
const persistentSessionsStore = createPersistentSessionsStorage(options);

if (
evt.value.options.renewMediaKeys !== true &&
canReuseMediaKeys() &&
currentState !== null &&
evt.type === "reuse-media-key-system-access"
Expand Down
57 changes: 54 additions & 3 deletions src/public_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,11 +559,62 @@ export interface IKeySystemOption {
*/
distinctiveIdentifier?: MediaKeysRequirement | undefined;
/**
* If true, all open MediaKeySession (used to decrypt the content) will be
* closed when the current playback stops.
* If true, all open `MediaKeySession` (JavaScript Objects linked to the keys
* used to decrypt the content) will be closed when the current playback
* stops.
*
* By default, we keep `MediaKeySession` from previous contents (up to
* `maxSessionCacheSize` `MediaKeySession`) to speed-up playback and avoid
* round-trips to the license server if the user ever decide to go back to
* those contents or to other contents relying to the same keys.
*
* However we found that some devices poorly handle that optimization.
*
* Note that if setting that property to `true` fixes your issue, it may be
* that it's just the `maxSessionCacheSize` which is for now too high.
*
* However if your problem doesn't disappear after setting
* `closeSessionsOnStop` to `true`, you may try `renewMediaKeys` next.
*/
closeSessionsOnStop?: boolean;

/**
* If `true`, we will create a new `MediaKeys` instance (a JavaScript object
* needed to decrypt contents) if needed for that content.
*
* If `false` or if not set, we might rely on the previous `MediaKeys` if a
* compatible one is already set on the media element, allowing to potentailly
* speed-up content playback.
*
* We noticed that reusing a previous MediaKeys had led to errors on a few
* devices. For example some smart TVs had shown errors after playing several
* encrypted contents, errors which disappeared if we "renewed" the
* `MediaKeys` for each content.
*
* We should already be able to detect most of those cases in the RxPlayer
* logic. However, it is still possible that we don't know yet of a device
* which also has problem with that optimization.
*
* If you have issues appearing only after playing multiple encrypted
* contents:
*
* - First, try setting the `closeSessionsOnStop` option which is less
* destructive.
*
* If it fixes your issue, it may be that it's just the number of
* `MediaKeySession` cached by the RxPlayer that is here too high.
*
* In that case you can instead update the `maxSessionCacheSize` option
* to still profit from a `MediaKeySession` cache (which avoid making
* license requests for already-played contents).
*
* If that second option doesn't seem to have an effect, you can just set
* `closeSessionsOnStop`.
*
* - If none of the precedent work-arounds work however, you can try setting
* `renewMediaKeys` to `true`. If it fixes your problem, please open an
* RxPlayer issue so we can add your device to our list.
*/
renewMediaKeys?: boolean | undefined;
singleLicensePer?: "content" | "periods" | "init-data";
/**
* Maximum number of `MediaKeySession` that should be created on the same
Expand Down

0 comments on commit 3fdedf5

Please sign in to comment.