-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: excessive requests when using HDCP fallback with LDL #225
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this change! License expiration/renewal cannot be effectively used for concurrency enforcement and detection if we attempt a renewal automatically on expiration.
One small thing, boolean flags make me nervous for some irrational reason, could we get a test around that flag and the new 'ended' logic?
@@ -160,6 +161,10 @@ export const makeNewRequest = (player, requestOptions) => { | |||
return; | |||
} | |||
|
|||
if (event.messageType === 'license-renewal' && (!player.hasStarted() || player.paused())) { | |||
return; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an attempt to reduce the number of license renewals made when the player is idle (before playback begins) or when the player is paused for too long.
A more ideal solution to this would probably be closing and removing the sessions if the player is abandoned in a paused state and then making a new request when unpaused. Maybe such a behavior should be behind an option where the amount of time to wait (before closing and removing the session) is specified ? But this might introduce some complications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the paused
check could cause a license to expire mid stream. Has this been tested? Curious if the player can recover the session after playback is resumed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To provide further context to what I'm asking here, I'm curious if the player sits either paused or before starting playback for the duration of a license and it expires, will we request a new license and recover upon resuming playback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made some changes to the previous logic. I've added an option limitRenewalsOnPauseTime
(which probably needs a better name) to define the number of seconds to wait in paused state before rejecting renewals and closing the session.
The player will request new license when playback resumes.
Session is closed when license-renewal is attempted after playback ends. New requests will be made on replay
or seek-back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it should be something like: limitRenewalsMaxPauseDuration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Just a couple more questions.
@@ -160,6 +161,10 @@ export const makeNewRequest = (player, requestOptions) => { | |||
return; | |||
} | |||
|
|||
if (event.messageType === 'license-renewal' && (!player.hasStarted() || player.paused())) { | |||
return; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the paused
check could cause a license to expire mid stream. Has this been tested? Curious if the player can recover the session after playback is resumed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks great! I left a few comments mainly relating to documentation.
handleEncryptedEvent(player, mockEncryptedEvent, getOptions(player), player.eme.sessions, player.tech_, emeError); | ||
}; | ||
|
||
if (videojs.browser.IS_FIREFOX) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would a comment describing why we are doing this only on Firefox be useful? I guess at first glance it isn't obvious why we are only sending the mock encrypted event in Firefox
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment!
src/eme.js
Outdated
let pauseTimer; | ||
|
||
player.on('pause', () => { | ||
if (options.limitRenewalsOnPauseTime && typeof options.limitRenewalsOnPauseTime === 'number') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to document the limitRenewalsBeforePlay
and limitRenewalsOnPauseTime
in the README?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated README in the latest commit!
@@ -231,29 +276,7 @@ export const makeNewRequest = (player, requestOptions) => { | |||
if (expired) { | |||
// Close session and remove it from the session list to ensure that a new | |||
// session can be created. | |||
videojs.log.debug('Session expired, closing the session.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We removed this debug statement and didn't add it back in closeAndRemoveSession
.. should we add something similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Added it back in closeAndRemoveSession
src/eme.js
Outdated
|
||
if (!player.hasStarted() && limitRenewalsBeforePlay || | ||
(player.paused() && typeof limitRenewalsOnPauseTime === 'number' && timeElapsed >= limitRenewalsOnPauseTime) || | ||
player.ended()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would split it into several consts eg:
ignoreLinceRenewal (before playback, max pause duration reached, ended)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
When we have HDCP fallback and short-duration license, there are excessive requests because we're renewing licenses and subsequently fetching new licenses if the renewal fails. This can be avoided by taking an approach similar to Shaka player by not requesting a new license when the old one expires.
The PR also provides an option to limit license renewals when the player is idle (before playback begins, after playback ends and player abandoned in paused state).
limitRenewalsBeforePlay
is set to true. New requests are made on 'play'limitRenewalsMaxPauseDuration
option