-
Notifications
You must be signed in to change notification settings - Fork 133
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
DRM: Create new persistent MediaKeySession when load fails #1139
DRM: Create new persistent MediaKeySession when load fails #1139
Conversation
* @param {MediaKeySession} session | ||
* @param {string} sessionId | ||
* @returns {Observable} | ||
* @returns {Promise.<boolean>} |
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.
All those modiications only concern the documentation.
I noticed it wasn't updated since we made the transition from Observable-based to Promise-based
// Thus, we're creating another `"persistent-license"` `MediaKeySession` | ||
// in that specific case: | ||
const newEntry = loadedSessionsStore.createSession(initData, | ||
"persistent-license"); |
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.
The main fix!
2149c45
to
7cb1ce0
Compare
We noticed of an issue which led to the impossibility of playing an encrypted content in a "persistent-license" mode if its license had already been persisted in the past but it could not be retrieved by the browser through the `MediaKeySession.load` API. This problematic situation only arises if the RxPlayer's persistent session storage, generally stored in `localStorage` by the application, is de-synchronized with the browser/CDM internal one, with the former having more items than the latter. Arguably that situation is not frequent: - we reproduced it at a large scale when updating the browser of some devices on which the RxPlayer runs. That update was not a small step (the two versions were released years apart), leading us to believe that that browser internal representation of persisted `MediaKeySession` had changed, thus it being not able to re-load old persistent `MediaKeySession`. Because the application kept however the same store of old persisted `MediaKeySession`, such de-synchronization was created. (To note that the RxPlayer currently has a policy of being retro-compatible by default - unless opted-out for performance reasons - when it comes to old persisted `MediaKeySession`, so updating the RxPlayer should normally not invalidate old persisted `MediaKeySession` the way it did for the browser here.) - In any case, we suppose that a browser or CDM may decide at any time to evict old persisted `MediaKeySession`. The RxPlayer also has an eviction mechanism in its own store but as both logics are completely un-synchronized, differences may appear in any time. --- The previous logic of the RxPlayer when failing to load an old persistent `MediaKeySession`'s information on a newly created one (as that's how the EME API works), was to just abort trying to load it and continue doing the license request on the same `MediaKeySession`. However, by re-reading the specification, it seems that this does not work. This is not indicated clearly however, but can be deduced by following the `unitialized` flag the EME specification brings up in some API's documentation. Reading the different algorithms proposed for the `load` and `generateRequest` methods, it appears that neither can be called after the other was on the same `MediaKeySession`, because this `unitialized` flag is set to `false`, having previously been asserted to be `true` right before the actual implementation logic is done. Even more implicit, it seems that it is not possible to `close` a `MediaKeySession` whose `load` call did not retrieve anything, by following this time an EME flag called `callable`. --- The (simple) fix for that situation, which remain to be tested, is to just throw away, without closing it, a `MediaKeySession` whose `load` call resolved with false, and to create a new one so that `generateRequest` can be called on it. Also, to prevent any issues (for now unseen) with that `callable` flag whose context appear more unclear, I chose to check if a `sessionId` is set on a persistent `MediaKeySession` whose closing operation failed, to ignore the failure if it wasn't and just continue the usual logic. I did that check in such a way because there seem to be a relation between a set (i.e. different than the empty string) `sessionId` and the `callable` flag though this is never clearly stated.
7cb1ce0
to
2baac94
Compare
We noticed of an issue which led to the impossibility of playing an encrypted content in a "persistent-license" mode if its license had already been persisted in the past but it could not be retrieved by the browser through the
MediaKeySession.load
API.This problematic situation only arises if the RxPlayer's persistent session storage, generally stored in
localStorage
by the application, is de-synchronized with the browser/CDM internal one, with the former having more items than the latter.Arguably that situation is not frequent:
we reproduced it at a large scale when updating the browser of some devices on which the RxPlayer runs.
That update was not a small step (the two versions were released years apart), leading us to believe that that browser internal representation of persisted
MediaKeySession
had changed, thus it being not able to re-load old persistentMediaKeySession
.Because the application kept however the same store of old persisted
MediaKeySession
, such de-synchronization was created.(To note that the RxPlayer currently has a policy of being retro-compatible by default - unless opted-out for performance reasons - when it comes to old persisted
MediaKeySession
, so updating the RxPlayer should normally not invalidate old persistedMediaKeySession
the way it did for the browser here.)In any case, we suppose that a browser or CDM may decide at any time to evict old persisted
MediaKeySession
.The RxPlayer also has an eviction mechanism in its own store but as both logics are completely un-synchronized, differences may appear at any time.
The previous logic of the RxPlayer when failing to load an old persistent
MediaKeySession
's information on a newly created one (as that's how the EME API works), was to just abort trying to load it and continue doing the license request on the sameMediaKeySession
.However, by re-reading the specification, it seems that this does not work. This is not indicated clearly however, but can be deduced by following the
unitialized
flag the EME specification brings up in some API's documentation.Reading the different algorithms proposed for the
load
andgenerateRequest
methods, it appears that neither can be called after the other was on the sameMediaKeySession
, because thisunitialized
flag is set tofalse
, having previously been asserted to betrue
right before the actual implementation logic is done.Even more implicit, it seems that it is not possible to
close
aMediaKeySession
whoseload
call did not retrieve anything, by following this time an EME flag calledcallable
.The (simple) fix for that situation, which remain to be tested, is to just throw away, without closing it, a
MediaKeySession
whoseload
call resolved with false, and to create a new one so thatgenerateRequest
can be called on it.Also, to prevent any issues (for now unseen) with that
callable
flag whose context appear more unclear, I chose to check if asessionId
is set on a persistentMediaKeySession
whose closing operation failed, to ignore the failure if it wasn't and just continue the usual logic.I did that check in such a way because there seem to be a relation between a set (i.e. different than the empty string)
sessionId
and thecallable
flag though this is never clearly stated.Because all this is only interpretation of the EME specification, I left big comments in the corresponding code with my name on it :p (git blame becomes rapidly unreliable and complex after multiple code refacto)