-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
feat: allow reuse of persistent license sessions #4461
feat: allow reuse of persistent license sessions #4461
Conversation
} | ||
|
||
// TODO: We should get a key status change event. Remove once Chrome CDM |
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.
ℹ️ Worked like a charm on Chrome, I might need to test the full offline capabilities
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.
Downloaded Widevine DRM content worked great with Chrome ;)
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.
What happens in old TV browsers?
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.
Haven't tested yet the persistent licenses on TV but will do
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.
Tizen 6.5
It correctly starts the persistent-license session at first launch but fails on the session load at second launch, so my guess is that this isn't supported.
The sessionId is always the same initialdrmsessionid
so I don't think it could work at all.
Shaka Error DRM.FAILED_TO_CREATE_SESSION (Failed to execute 'load' on 'MediaKeySession': Loading session failed. . (2))
webOS 5.0
It fails to request a media key system access when asking for a persistent-license
with the error REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE
, so it seems it doesn't support persistent license at all
So my overall conclusion is persistent license isn't supported on TV devices, so I don't think we need to go further into making this feature working on those devices.
Error Recoverability
It pointed me out on an issue with my code where fails to load a persistent license will stop the player, rather than trying to fetch a new one (intended behaviour).
I have two options for that, let me know what you prefer (my pref is option 1):
- Option 1: Send a RECOVERABLE error
this.onError_(new shaka.util.Error(
this.config_.persistentSessionOnlinePlayback ?
shaka.util.Error.Severity.RECOVERABLE : shaka.util.Error.Severity.CRITICAL;
shaka.util.Error.Category.DRM,
shaka.util.Error.Code.FAILED_TO_CREATE_SESSION,
error.message));
- Option 2: Bypass the error, only log something:
if (this.config_.persistentSessionOnlinePlayback) {
shaka.log.warning('Persistent session', sessionId, 'not available');
} else {
this.onError_(new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.DRM,
shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));
return Promise.resolve();
}
Incremental code coverage: 90.85% |
Related to #1956 |
@@ -617,23 +636,40 @@ shaka.media.DrmEngine = class { | |||
* | |||
* @return {!Promise} | |||
*/ | |||
createOrLoad() { | |||
// Create temp sessions. | |||
async createOrLoad() { |
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 noticed that the attach(video) function calls createOrLoad() but does not wait for the returned promise to resolve. Should it wait?
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 think it was done on purpose so that creating / loading sessions could be done in parallel of fetching manifest information, segments and more.
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.
In general, LGTM, but I think we should give the possibility (player configuration) that ShakaPlayer itself stores this information in localStorage for example.
@valotvince it seems that there are some conflict with the main branch, can you rebase? Thanks! |
da2d158
to
e00ec59
Compare
c1880a2
to
8ee4eba
Compare
👋 @avelad @joeyparrish I've rebased on main & added documentation about the feature, could you review it again ? Thanks :)
If that's possible I'd like it to be done in another PR, as localStorage (or Indexeddb) is not necessarily the best on some devices. It might take more reflexion on the whole storage capabilities of Shaka, like allowing to give a StorageManager like the ABRManager which would handle the storage, without Shaka's knowing what the storage is. |
Hi @avelad @joeyparrish, any comments to share on this PR ? Thanks ! |
externs/shaka/player.js
Outdated
* }} | ||
* | ||
* @description | ||
* DRM Session Metadata for as 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.
The JSDoc for this is the same as DrmSessionMetadata
, but the two represent different types of data.
From what I gather, PersistentSessionMetadata
is the type that the user passes in, representing an existing persistent session. Meanwhile, DrmSessionMetadata
represents an active session, which may have come from this playback or have been loaded from a persistent session.
Correct?
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.
You are correct ! :)
this.onError_(new shaka.util.Error( | ||
shaka.util.Error.Severity.CRITICAL, | ||
severity, | ||
shaka.util.Error.Category.DRM, | ||
shaka.util.Error.Code.OFFLINE_SESSION_REMOVED)); |
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 JSDoc for OFFLINE_SESSION_REMOVED
should probably be updated. Right now it specifically says "The content is not playable", which is no longer going to be true if this error will sometimes be recoverable.
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'll change the description of the error to:
A required offline session was removed. The content might not be playable depending of the playback context.
metadata.loaded = true; | ||
if (this.areAllSessionsLoaded_()) { | ||
this.allSessionsLoaded_.resolve(); | ||
metadata.loaded = true; |
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 really need to set metadata.loaded
to true
here?
All that value does is determine when areAllSessionsLoaded_
returns true
. So if we are manually setting this to true for each stream we call loadOfflineSession_
on, and we call createOrLoad
on each session at once inside createOrLoad
, doesn't that mean that we will just immediately resolve this.allSessionsLoaded_
when the last session begins to load? That seems like it defeats the purpose of waiting for the key status change event, if we're still resolving before the event fires.
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 only set metadata.loaded
when the session is not present anymore (we will never receive a keystatuschange
event), and send a OFFLINE_SESSION_REMOVED
event.
If other sessions are present & correctly loaded, we wait for the keystatuschange
to set the session as loaded.
expect(session2.generateRequest).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it( |
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 think this would fit into one line. No need to do the weird indenting.
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 whole line
it('tries persistent session ids before requesting a license', async () => {
is 81 characters long 😞
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.
LGTM, can you rebase and resolve the conflicts? Thanks!
f0e9fec
to
5f8bf6f
Compare
@avelad 👋 Rebase done ! |
}); | ||
``` | ||
|
||
NB: Shaka doesn't provide a out-of-the-box storage mechanism for the sessions |
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.
There is such a mechanism in the offline/ codebase. We could discuss a follow-up PR to use that mechanism if/when offline support is included.
Failed tests look like unrelated flakiness, but I'm re-running them just to be sure. |
Add capability to re-use persistent license sessions across sessions.
DrmEngine will now always:
Given the flag
persistentSessionOnlinePlayback
is true, DrmEngine:For now, it needs Shaka's users to persist session information by themselves (localStorage, IndexDB, ...) before giving it back for the next session. Still, it lays foundation to develop the feature to fully handling it on Shaka's side.
TBD:
offlineSessionIds_
in DrmEngine tostoredPersistentSessionIds_
because we now use those in two different contexts, online / offline (and in comments too) (after full review to avoid noise over the feature)loadOfflineSession_
in DrmEngine toloadStoredPersistentSession_
(after full review to avoid noise over the feature)Related to #1956