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

Multiple persistent license requests are going to download an offline widevine license. #149

Closed
anysongs opened this issue Mar 21, 2023 · 6 comments

Comments

@anysongs
Copy link

Multiple persistent license requests are going to download an offline widevine license.

CastLabs Electron Version : 6.0.1

Shakaplayer version : 2.0

Python : 3.9.0

exe name : electron.exe
After EVS sign process compete it create electron.exe.sig

I haven't done any codesign or EVS signing processes for my application yet. We have a thousand files there to download as offline licenses. It takes too much time. Now we are trying to optimise offline license download time. Till now, Shakaplayer has requested two persistent license requests for each offline license download. To reduce the time, we want to make one request for each offline license download. As per my understanding, we need to create a Verified Media Path (VMP), after the EVS sign completes, It will reduce the request count to one. For that, I followed the CastLabs electron documentation and tried to do EVS sign to my exe using the python3 -m castlabs_evs.vmp sign-pkg --persistent path/to/package-directroy command, and the electron.exe.sig file was successfully generated. Then also shaka making two requests. Is there anything I missed during the EVS signing process? Is there another way to reduce the number of persistent license requests?

image

@khwaaj
Copy link
Collaborator

khwaaj commented Mar 21, 2023

The number of requests sent has nothing to do with VMP, however the ability to use persistent licenses at all does. Also, if you are on ECS version 6 you should really consider updating, it is very old and not even officially supported anymore by the Widevine CDM. The official requirement is at least Chromium M95, which means ECS 16 or later (although it may still work with earlier versions, for now).

About your problem, I can't tell for sure by your picture, but my guess is that the first request for each session is a service certificate request. This can be avoided if you provide the cert ahead of time, or load it once and then reuse it. This Shaka Player tutorial has some examples: https://shaka-player-demo.appspot.com/docs/api/tutorial-widevine-service-certs.html

@anysongs
Copy link
Author

@khwaaj ,Thank you for your information. I added the serverCertificate as you suggested and shared my configuration, but two requests are still being processed. 

 const req = await fetch('https://drm-widevine/ServiceCertificate');
  const cert = new Uint8Array(await req.arrayBuffer());
player.configure({
    drm: {
      servers: { 'com.widevine.alpha': 'https://ifp.drm.in/persistentlicense' },
      advanced: {
        'com.widevine.alpha': {
          'persistentStateRequired': true,
          'serverCertificate': cert
        }
      }
    },
    preferredTextLanguage: 'eng',
    streaming: {
      alwaysStreamText: true,
      ignoreTextStreamFailures: true
    },
    retryParameters: {
    maxAttempts: 1,   // the maximum number of requests before we fail
  }
  });

ServiceCertificate Response :

image

Persistentlicense first Request Response:

image

Should the responses to these two requests be the same? I noticed a small difference in the first line between two responses; Is this the problem? Did I miss anything? Can you tell me why two requests are still being processed?

@khwaaj
Copy link
Collaborator

khwaaj commented Mar 23, 2023

Are you sure there are not just two sets of keys for Widevine defined in the MPD you are downloading (e.g. for different tracks or qualities)?

@anysongs
Copy link
Author

@khwaaj ,We are maintaining one key for each MPD.

<?xml version="1.0" encoding="UTF-8"?><MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" mediaPresentationDuration="PT303.6430969238281S" minBufferTime="PT2S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd">
  <Period id="0">
    <AdaptationSet contentType="audio" id="0" lang="en" subsegmentAlignment="true">
      <Representation audioSamplingRate="44100" bandwidth="133490" codecs="mp4a.40.2" id="0" mimeType="audio/mp4">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
        <ContentProtection cenc:default_KID="0002a4b8-2f85-422e-a3ab-5d7ebb4521a8" schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
        <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
          <cenc:pssh>AAAA5HBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAMQSEO1BVZnXRkPijde+bN2zVHISEEcQLJTQRkijld95nD8fsZcSEAVCtymLd0hfrjZSprzdMgYSEELRRnLdckCRsM+gecb9yQASEJlQ/XUyK0T4imJSrPzD+3MSEKAsop0PEUl7lonjrkm7eaESEAUBZzFuDk5UtOehiuQjGCESELr087QQkECGpEAS7UD9sFYSEFGoE5qeOUr0pRRnNTf9/g0SECMHeeT1REaTvE4rqkYPd7UaDk5leHQgRWR1Y2F0aW9u</cenc:pssh>
        </ContentProtection>
        <BaseURL>476f1e12-ca55-4b5e-a34d-3563f18be5f5.app</BaseURL>
        <SegmentBase indexRange="935-4542" timescale="44100">
          <Initialization range="0-934"/>
        </SegmentBase>
      </Representation>
      <Representation audioSamplingRate="44100" bandwidth="165490" codecs="mp4a.40.2" id="2" mimeType="audio/mp4">
        <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
        <ContentProtection cenc:default_KID="0002a4b8-2f85-422e-a3ab-5d7ebb4521a8" schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
        <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
          <cenc:pssh>AAAA5HBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAMQSEO1BVZnXRkPijde+bN2zVHISEEcQLJTQRkijld95nD8fsZcSEAVCtymLd0hfrjZSprzdMgYSEELRRnLdckCRsM+gecb9yQASEJlQ/XUyK0T4imJSrPzD+3MSEKAsop0PEUl7lonjrkm7eaESEAUBZzFuDk5UtOehiuQjGCESELr087QQkECGpEAS7UD9sFYSEFGoE5qeOUr0pRRnNTf9/g0SECMHeeT1REaTvE4rqkYPd7UaDk5leHQgRWR1Y2F0aW9u</cenc:pssh>
        </ContentProtection>
        <BaseURL>fb60d682-e3f6-4ade-8601-a6fb9df81d21.app</BaseURL>
        <SegmentBase indexRange="935-4542" timescale="44100">
          <Initialization range="0-934"/>
        </SegmentBase>
      </Representation>
    </AdaptationSet>
    <AdaptationSet contentType="video" frameRate="30000/1001" id="1" maxHeight="720" maxWidth="1280" par="16:9">
      <Representation bandwidth="681243" codecs="avc1.42c01e" height="360" id="1" mimeType="video/mp4" sar="1:1" width="640">
        <ContentProtection cenc:default_KID="0002a4b8-2f85-422e-a3ab-5d7ebb4521a8" schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
        <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
          <cenc:pssh>AAAA5HBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAMQSEO1BVZnXRkPijde+bN2zVHISEEcQLJTQRkijld95nD8fsZcSEAVCtymLd0hfrjZSprzdMgYSEELRRnLdckCRsM+gecb9yQASEJlQ/XUyK0T4imJSrPzD+3MSEKAsop0PEUl7lonjrkm7eaESEAUBZzFuDk5UtOehiuQjGCESELr087QQkECGpEAS7UD9sFYSEFGoE5qeOUr0pRRnNTf9/g0SECMHeeT1REaTvE4rqkYPd7UaDk5leHQgRWR1Y2F0aW9u</cenc:pssh>
        </ContentProtection>
        <BaseURL>255b84ac-e9ae-45d0-9b9c-badb77dd27f3.app</BaseURL>
        <SegmentBase indexRange="998-2277" timescale="30000">
          <Initialization range="0-997"/>
        </SegmentBase>
      </Representation>
      <Representation bandwidth="2233220" codecs="avc1.42c01f" height="720" id="3" mimeType="video/mp4" sar="1:1" width="1280">
        <ContentProtection cenc:default_KID="0002a4b8-2f85-422e-a3ab-5d7ebb4521a8" schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
        <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
          <cenc:pssh>AAAA5HBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAMQSEO1BVZnXRkPijde+bN2zVHISEEcQLJTQRkijld95nD8fsZcSEAVCtymLd0hfrjZSprzdMgYSEELRRnLdckCRsM+gecb9yQASEJlQ/XUyK0T4imJSrPzD+3MSEKAsop0PEUl7lonjrkm7eaESEAUBZzFuDk5UtOehiuQjGCESELr087QQkECGpEAS7UD9sFYSEFGoE5qeOUr0pRRnNTf9/g0SECMHeeT1REaTvE4rqkYPd7UaDk5leHQgRWR1Y2F0aW9u</cenc:pssh>
        </ContentProtection>
        <BaseURL>87ef587d-d764-4ae2-9c44-55d2ea37d45f.app</BaseURL>
        <SegmentBase indexRange="997-2300" timescale="30000">
          <Initialization range="0-996"/>
        </SegmentBase>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

I am sharing an MPD file data. Can you please check and let me know if there is any issue with my MPD? If issue not releated to MPD , is issue with  servicecertificate response  and persistentlicense first request response, As I replayed the last thread, I noticed a small difference in the first line between two responses. Is this the problem?

@khwaaj
Copy link
Collaborator

khwaaj commented Mar 28, 2023

The MPD looks mostly ok, however the DASH-IF implementation guidelines specifies that SHALL be present in the AdaptationSet element and apply to all contained Representations, so that could be one thing to improve. I doubt it is the culprit here though.

As I replayed the last thread, I noticed a small difference in the first line between two responses. Is this the problem?

I can't easily tell what this is without request/response headers. The certificate request has just a 2-byte request payload, so that is an easy way to distinguish it. License requests are much larger.

Ultimately this is not an issue with ECS, it is with the player implementation (and/or content DRM integration). You would see the exact same behavior executing the same code in Chrome. ECS provides the interface to the CDM, which is used through EME by the player, nothing else. It could be that Shaka is creating separate EME sessions for A/V (since both are present in the manifest), requesting keys for both sessions even though the keys are really the same. I'm not very familiar with the Shaka implementation though so it is just speculation (although having separate A/V key is standard practice for DRM protected content, so it would make some sense). My points that you are probably better off asking in a Shaka forum.

@anysongs
Copy link
Author

@khwaaj
Shakaplayer storage.store flow serverCertificate will not be honoured. With some custom changes in Shakeplayer code working now thanks for your support

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

No branches or pull requests

2 participants