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

Requests made to Widevine licenses server proxy at playback time of offline stored content, despite persistent license storage is supported #6141

Closed
loicraux opened this issue Jan 23, 2024 · 6 comments · Fixed by #6143
Labels
component: offline The issue involves the offline storage system of Shaka Player priority: P1 Big impact or workaround impractical; resolve before feature release status: archived Archived and locked; will not be updated type: bug Something isn't working correctly
Milestone

Comments

@loicraux
Copy link
Contributor

Have you read the FAQ and checked for duplicate open issues?
Yes

If the problem is related to FairPlay, have you read the tutorial?
N/A, I am only using Widevine.

What version of Shaka Player are you using?
Latest version 4.7.6

Can you reproduce the issue with our latest release version?
Yes

Can you reproduce the issue with the latest code from main?
Yes

Are you using the demo app or your own custom app?
Custom app, based on CastLabs's electron release (read below)

If custom app, can you reproduce the issue using our demo app?
N/A

What browser and OS are you using?
Windows, Chrome 120.0.6099.199 in VPM-signed Electron 28.1.3

For embedded devices (smart TVs, etc.), what model and firmware version are you using?
N/A

What are the manifest and license server URIs?
Manifest URI : https://boutique-arte-streams.lab.arte.tv/origin/HLS_139940_0-VOF-cenc.ism/stream.mpd

License server URI : https://widevine-dash.ezdrm.com/proxy?username=s-oualid%40artefrance.fr&contentId=HDS_139940_0-VOF&PX-BASEDC

What configuration are you using? What is the output of player.getConfiguration()?
See below...

What did you do?
I've created a prototype of offline player for protected (by Widevine DRM) videos.

I make use of Shaka-Player (latest version 4.7.6), the DRM provider EZDRM and a special release of Electron made by CastLabs, called ECS. Electron for Content Security (ECS) is a fork of Electron created by castLabs to facilitate the use of Google's Widevine Content Decryption Module (CDM) for DRM-enabled playback within Electron, including support for Verified Media Path (VMP) and persistent license storage. It is intended to be used as a drop-in replacement for stock Electron and currently has full support for Windows and macOS platforms, with partial support for Linux (which lacks support for persistent licenses due to VMP limitations on the platform).

Note that I am using Windows.

Since the video content I want to play is production content, I am not using Widevine UAT servers accepting development clients, consequently I have to VMP-sign my electron binary for production, using CastLabs's Cloud-based EVS service :

python3 -m castlabs_evs.vmp sign-pkg --persistent node_modules/electron/dist/

The electron.exe is correctly signed :

Signing: node_modules/electron/dist\electron.exe
 - Verifying existing VMP signature
 - Signature invalid: Certificate is valid for development only
 - Verifying matching VMP signature in cache
 - Signature is valid [persistent, 2368 days of validity], use cached signature

I can also check that with the following command :

python3 -m castlabs_evs.vmp verify-pkg --persistent node_modules/electron/dist/
Verifying signature for: node_modules/electron/dist\electron.exe
 - Signature is valid [persistent, 2368 days of validity]

To download offline content, here is basically my shaka-player setup :

    const GOOGLE_WIDEVINE_KEY_SYSTEM = 'com.widevine.alpha';

    const { drm } = await shaka.Player.probeSupport();
    const arePersistentLicensesSupported = drm[GOOGLE_WIDEVINE_KEY_SYSTEM]?.persistentState ?? false;
    logInfo(`Persistent licenses are ${arePersistentLicensesSupported ? 'supported' : 'not supported'}`);

    player.configure({
        drm: {
            logLicenseExchange: true, // TODO: change value depending on build mode.
            preferredKeySystems: [GOOGLE_WIDEVINE_KEY_SYSTEM],
            // True to configure drm to try playback with given persistent session ids
            // before requesting a license. Also prevents the session removal at playback stop,
            // as-to be able to re-use it later :
            persistentSessionOnlinePlayback: arePersistentLicensesSupported,
            advanced: {
                [GOOGLE_WIDEVINE_KEY_SYSTEM]: {
                    videoRobustness: 'SW_SECURE_CRYPTO',
                    audioRobustness: 'SW_SECURE_CRYPTO',
                    // True if the application requires the key system to support persistent state,
                    // e.g., for persistent license storage :
                    persistentStateRequired: arePersistentLicensesSupported
                }
            },
            servers: {
                [GOOGLE_WIDEVINE_KEY_SYSTEM]: getLicenseServerUrl(username, video)
            }
        },
        offline: {
            usePersistentLicense: arePersistentLicensesSupported,
            progressCallback,
            trackSelectionCallback
        }
    });

Then I use storage.store API from shaka-player to download the contents... Everything is OK, two POST requests are made to EZDRM's widevine license server proxy, and both are successfum (HTTP code 200 returned)

Creating new persistent-license session
shaka-player-ui.js?v=8001658b:2116 EME init data: type= cenc data= AAAAVHBzc2gAAAAA7e-LqXnWSs6jyCfc1R0h7QAAADQIARIQqZxKFTq9VH6BOWGMTUmCYhoIbW92aWRvbmUiEMyRd5Wf9b9NiYMUxq-hK58qAlNE
shaka-player-ui.js?v=8001658b:2116 EME license request ...
shaka-player-ui.js?v=8001658b:2116 EME license response ...
shaka-player-ui.js?v=8001658b:2116 EME license request ...
shaka-player-ui.js?v=8001658b:2116 EME license response ...

Here is the content in the IndexDB shaka_offline_db database manifest_v5 table :

drmInfo:
    audioRobustness: "SW SECURE CRYPTO"
    distinctiveIdentifierRequired: false
    ▼initData: Array(0)
        length: 0
    keyIds: Set(1)
        ▼[[Entries]]
        ▼0: "a99c4a153abd547e8139618c4d498262"
            value: "a99c4a153abd547e8139618c4d498262"
        size: 1
    keysystem: "com.widevine.alpha"
    licenseServerUri: "https://widevine-dash.ezdrm.com/proxy?username=xyz%40artefrance.fr&contentId=HDS_139940_0-VOF&PX-BASEDC"
    persistentStateRequired: true
    ▾ serverCertificate: Uint8Array(0)
        buffer: ArrayBuffer(0)
        bytetength: 0
        byteoffset: 0
        length: 0
        Symbol(Symbol.toStringTag): "Uint8Array"
    serverCertificateUri: ""
    sessionType: "persistent-license"
    videoRobustness: "SW SECURE CRYPTO"
duration: 730.090666
expiration: Infinity
isIncomplete: false
originalManifesturi: "https://boutique-arte-streams.lab.arte.tv/origin/HLS_139940_0-VOF-cenc.ism/stream.mpd"
sequenceMode: false
▼sessionIds: Array(0)
    length: 0
size: 57083255
streams: Array(2)
    : {id: 3, originalid: 'audio=192000', groupId: null, primary: true, type: 'audio', } 1: (id: 5, originalld: 'video-424000', groupId: null, primary: true, type: 'video', )
    length: 2
type: "DASH"

What did you expect to happen?
Now, once the download is complete, I go offline and I attempt to play the downloaded contents. I would expect no HTTP requests to be made to EZDRM's widevine licenses server proxy

I would expect playback of offline content not to require any network connection, since I have set usePersistentLicense to true and persistent license storage is supported by my VPM-signed ECS...

What actually happened?
Two requests (probably because drm.retryParameters.maxAttempts is set to 2 ?) are made, which obvisouly fails since there is no network connectivity....

Consequently, the playback of the video when offline does not work...

What could cause shaka-player to request once again license at playback time ? I can't find the reason why... (tell me if you need additional details !)

Additional observations
What I have also observed (Idk if this can be of any help ?) is that in the IndexDB "shaka_offline_db" database, the session-ids table is empty... I don't know if this is normal or not ? Where is the persistent license stored ?

@loicraux loicraux added the type: bug Something isn't working correctly label Jan 23, 2024
@avelad
Copy link
Collaborator

avelad commented Jan 23, 2024

@loicraux can you try to download the content in the demo over Chrome and see the results? Thanks!

@avelad
Copy link
Collaborator

avelad commented Jan 23, 2024

Also try not to set drm.advanced[WIDEVINE].persistentStateRequired and see the results

@avelad avelad added status: waiting on response Waiting on a response from the reporter(s) of the issue component: offline The issue involves the offline storage system of Shaka Player component: Widevine The issue involves the Widevine DRM labels Jan 23, 2024
@shaka-bot shaka-bot added this to the v5.0 milestone Jan 23, 2024
@loicraux
Copy link
Contributor Author

@loicraux can you try to download the content in the demo over Chrome and see the results? Thanks!

I have the same results when trying to download the content in the Shaka Player demo over Chrome on Windows :

Manifest URL is : https://boutique-arte-streams.lab.arte.tv/origin/HLS_139940_0-VOF-cenc.ism/stream.mpd

Custom License Server URL is : https://widevine-dash.ezdrm.com/proxy?username=artevod_s-oualid%40artefrance.fr&contentId=HDS_139940_0-VOF&pX=BA5EDC

Extra config is :

{
  "drm": {
    "preferredKeySystems": ["com.widevine.alpha"],
    "persistentSessionOnlinePlayback": true,
    "advanced": {
      "com.widevine.alpha": {
        "videoRobustness": "SW_SECURE_CRYPTO",
        "audioRobustness": "SW_SECURE_CRYPTO",
        "persistentStateRequired": true
      }
    }
  },
  "offline": {
    "usePersistentLicense": true
  }
}

In Chrome on Windows, I click on the download button, content is downloaded OK, but when I hit the play button, I observe the same : Two requests are made to the EZDRM licenses server proxy .... ?

Note : I observe the same if drm.advanced[WIDEVINE].persistentStateRequired is not set. I also observe the same if drm.persistentSessionOnlinePlayback is not set. And the same with an extra config as simple as :

{
  "offline": {
    "usePersistentLicense": true
  }
}

@loicraux
Copy link
Contributor Author

Also try not to set drm.advanced[WIDEVINE].persistentStateRequired and see the results

This makes no changes. Two requests are still made at playback time.

@shaka-bot shaka-bot removed the status: waiting on response Waiting on a response from the reporter(s) of the issue label Jan 23, 2024
@avelad
Copy link
Collaborator

avelad commented Jan 23, 2024

I have found an error in the code, I will upload a fix soon. Thanks!

@avelad avelad added the priority: P1 Big impact or workaround impractical; resolve before feature release label Jan 23, 2024
@avelad avelad removed the component: Widevine The issue involves the Widevine DRM label Jan 23, 2024
@loicraux
Copy link
Contributor Author

I have found an error in the code, I will upload a fix soon. Thanks!

Thanks for the analysis & PR !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
component: offline The issue involves the offline storage system of Shaka Player priority: P1 Big impact or workaround impractical; resolve before feature release status: archived Archived and locked; will not be updated type: bug Something isn't working correctly
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants