Many DRM session created
Hello,
Since release 3.27.0, the player creates many temporary DRM sessions, triggering many calls to our license server.
It seems that the current algorithm creates a new DRM session for each keyId instead of re-using an already created session. We are using DASH + Widevine.
Here are the logs of a DRM session :
DRM: Clearing-up DRM session.
DRM: Nothing to clear. Returning right away. No state = true
DRM: Searching for compatible MediaKeySystemAccess
DRM: Found compatible keysystem com.widevine.alpha 1
DRM: Calling createMediaKeys on the MediaKeySystemAccess
DRM: MediaKeys created with success
DRM: Attaching MediaKeys to the media element
DRM: MediaKeys attached with success
DRM: Creating a new temporary session
DRM: Binding session events
DRM: Creating a new temporary session
DRM: Binding session events
DRM: Creating a new temporary session
DRM: Binding session events
DRM: Received message event, type license-request 9F5D37EFCFD88814BA1D701CC7345AC7
DRM: Received message event, type license-request 1E6586EA9642D5909B05DA17C40A9677
DRM: Received message event, type license-request A73E03F09FC93FA1FA2537BEBC3EA6AF
DRM: Updating MediaKeySession with message
DRM: MediaKeySession update succeeded.
DRM: keystatuseschange event received 9F5D37EFCFD88814BA1D701CC7345AC7
The kind of manifest we use :
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" publishTime="2022-11-22T15:40:13Z" availabilityStartTime="1970-01-01T00:00:00Z" minimumUpdatePeriod="PT2S" minBufferTime="PT6.4S" timeShiftBufferDepth="PT14400S" suggestedPresentationDelay="PT9.6S">
<Period id="0" start="PT0S">
<AdaptationSet id="0" group="1" segmentAlignment="true" startWithSAP="1" contentType="video">
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"><cenc:pssh>AAAAiHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAGgIARIQH7rsOV0BM3TmyyBxB90bChIQx49W2DcwfMI0bsq178WDyBIQTPw+QqeiYd3hKULfDtNe5BIQEqP6hNUWi6TrJMz14RSXARIQWA0ccDTY6BgjdP53xHdJoBoAKgAyADgASABQAA==</cenc:pssh></ContentProtection>
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="4cfc3e42-a7a2-61dd-e129-42df0ed35ee4"/>
<Representation id="379" bandwidth="400000" codecs="avc1.64000d" mimeType="video/mp4" width="384" height="216" frameRate="25">
<SegmentTemplate timescale="90000" initialization="0_1_379_init" media="0_1_379_$Time$">
<SegmentTimeline>
<S t="150220548414304" d="288000" r="4501"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
...
</AdaptationSet>
<AdaptationSet id="376" group="2" segmentAlignment="true" startWithSAP="1" contentType="audio" lang="fra">
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"><cenc:pssh>AAAAiHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAGgIARIQH7rsOV0BM3TmyyBxB90bChIQx49W2DcwfMI0bsq178WDyBIQTPw+QqeiYd3hKULfDtNe5BIQEqP6hNUWi6TrJMz14RSXARIQWA0ccDTY6BgjdP53xHdJoBoAKgAyADgASABQAA==</cenc:pssh></ContentProtection>
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="580d1c70-34d8-e818-2374-fe77c47749a0"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="376" bandwidth="64000" codecs="mp4a.40.2" mimeType="audio/mp4">
<SegmentTemplate timescale="90000" initialization="0_1_376_init" media="0_1_376_$Time$">
<SegmentTimeline>
<S t="150220548289380" d="288000" r="4502"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
...
</Period>
</MPD>
La payload de notre loadVideo :
const options = {
url,
transport: 'dash',
autoPlay: true,
keySystems: [{
type: 'widevine',
fallbackOn: {
keyInternalError: true,
keyOutputRestricted: true
},
getLicence
}]
};
player.loadVideo(options);
After further investigation, I found we are comparing keyIds filled with zero.
Added debug logs in KeySessionRecord.isCompatibleWith
KeySessionRecord.isCompatibleWith areAllKeyIdsContainedIn(keyIds, this._keyIds) false keyIds 4cfc3e42a7a261dde12942df0ed35ee4, 00000000000000000000000000000000 this._keyIds 4cfc3e42a7a261dde12942df0ed35ee4, 580d1c7034d8e8182374fe77c47749a0, 12a3fa84d5168ba4eb24ccf5e1149701, 1fbaec395d013374e6cb207107dd1b0a, c78f56d837307cc2346ecab5efc583c8 [key_session_record.js:142:17](http://localhost:5173/@fs/home/cbosse/Workspaces/player/rx-player/dist/_esm5.processed/core/decrypt/utils/key_session_record.js?t=1669204874185)
KeySessionRecord.isCompatibleWith areAllKeyIdsContainedIn(keyIds, this._initializationData.keyIds) false keyIds 4cfc3e42a7a261dde12942df0ed35ee4, 00000000000000000000000000000000 this._initializationData.keyIds 4cfc3e42a7a261dde12942df0ed35ee4, 580d1c7034d8e8182374fe77c47749a0, 12a3fa84d5168ba4eb24ccf5e1149701, 1fbaec395d013374e6cb207107dd1b0a, c78f56d837307cc2346ecab5efc583c8
I have found 2 issues so far.
- The zero filled
keyIdcomes from our MP4 init fragment. - The
KeySessionRecord.associateKeyIdshappens after the nextContentDecryptor.onInitializationData
I have added a check about the keyId. But I am not sure how to delay onInitializationData after keyIds have been associated to the current session.
Hi,
Sorry for the late response. If I follow correctly, you have a content with two keys, one for video and one for audio, yet the RxPlayer re-ask for a key it should already have? Does it stops after a time (for example, once every qualities have been switched to)?
And you think that this is due to the key-id containing all 0? For which PSSH, widevine? That's possible, but I'm unsure of why for now.
The MPD also does not list any key-id set to 0 and the RxPlayer does not parse the PSSH for DASH contents, so I'm unsure of how it can know about that 0 key-id before creating a MediaKeySession here.
You're right to look around the KeySessionRecord concept as it is the element storing which key(s) a MediaKeySession is linked to. If MediaKeySession are re-created, it should be because an old one was thought to be incompatible with it and we find out this mainly by checking its KeySessionRecord's isCompatibleWith method.
The zero keyId doesn't come from PSSH from DASH, but from the init MP4 segment.
Yes we have keyId for each AdaptationSet type. RxPlayer doesn't ask for a for a key but plays fine now that I have fixed the zero filled keyId issue. However it triggers 3 license-request to our Widevine server instead of 1, same forlicence-renewal.
My understading is that we have to discover all manisfest keyIds before trying to create a new session.
Have you set singleLicensePer to "content" in loadVideo() keySystems options ? If not, it defaults to "init-data" and you get one license request per content key, here 2. Of the 3 license requests, the 1st one occurring may be the initial request for a Widevine service certificate, which you can avoid I think by setting it statically through the serverCertificate option.
Yes I tried it, and it leads me to another issue: API: The player stopped because of an error TypeError: chosenRepFromBandwidth is undefined.
I have not investigated further.