Skip to content
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

Many DRM session created #1183

Open
el-gringo opened this issue Nov 22, 2022 · 6 comments
Open

Many DRM session created #1183

el-gringo opened this issue Nov 22, 2022 · 6 comments

Comments

@el-gringo
Copy link

el-gringo commented Nov 22, 2022

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);
@el-gringo
Copy link
Author

el-gringo commented Nov 23, 2022

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

@el-gringo
Copy link
Author

I have found 2 issues so far.

  • The zero filled keyId comes from our MP4 init fragment.
  • The KeySessionRecord.associateKeyIds happens after the next ContentDecryptor.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.

@peaBerberian
Copy link
Collaborator

peaBerberian commented Nov 24, 2022

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.

@el-gringo
Copy link
Author

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.

@lfaureyt
Copy link
Contributor

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.

@el-gringo
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants