canalplus / rx-player

DASH/Smooth HTML5 Video Player

Home Page:https://developers.canal-plus.com/rx-player/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

INCOMPATIBLE_KEYSYSTEMS error using DASH/Widevine on Panasonic 2019

peijkelhardt opened this issue · comments

When testing RxPlayer (version 3.29.0) on a Panasonic 2019 model, I encountered the following error while trying to play a DASH/Widevine stream:

EncryptedMediaError (INCOMPATIBLE_KEYSYSTEMS) No key system compatible with your wanted configuration has been found in the current browser

Sample code:

player.loadVideo({
    transport: "dash",
    url: [redacted].index.mpd,
    keySystems: [
        {
            type: "widevine",
            getLicense: function(message) { ... },
            getLicenseConfig: {
                retry: 5,
                timeout: 30000,
            },
            fallbackOn: {
                keyInternalError: true,
                keyOutputRestricted: true,
            },
            disableMediaKeysAttachmentLock: true,
            closeSessionsOnStop: true,
            serverCertificate: ...
        }
    ],
    autoPlay: true,
    startAt: undefined,
    enableFastSwitching: "false",
    onCodecSwitch: "reload",
    textTrackMode: "html",
    textTrackElement: document.CreateElement("div"),
});

When checking the same stream with Shaka Player, playback can be started without issues. So, at first glance it appears that the TV should support the supplied source & that RxPlayer incorrectly throws this error message.

In addition to above I've set LogLevel to DEBUG, which showed me this info:

DRM: Starting ContentDecryptor logic.
DRM: Searching for compatible MediaKeySystemAccess
DRM: Request keysystem access com.widevine.alpha,1 of 1
DRM: Rejected access to keysystem com.widevine.alpha 1

Hi,

The INCOMPATIBLE_KEYSYSTEMS error is thrown when the given keySystems configuration is not compatible with the device.

Are you sure that widevine is available on this device? Perhaps the key system string is slightly different? It could also be the MediaKeySystemConfiguration which is not compatible but I do not see anything too out there here.

In the end, we could be looking at what the shaka is asking for by monkey-patching the navigator.requestMediaKeySystemAccess API.

Hi,

The INCOMPATIBLE_KEYSYSTEMS error is thrown when the given keySystems configuration is not compatible with the device.

Are you sure that widevine is available on this device? Perhaps the key system string is slightly different? It could also be the MediaKeySystemConfiguration which is not compatible but I do not see anything too out there here.

In the end, we could be looking at what the shaka is asking for by monkey-patching the navigator.requestMediaKeySystemAccess API.

According to the documentation from Panasonic, Widevine is supported:

  • 2017-: Widevine Modular version 3.0.5
  • Supported with security level L1

Furthermore, when monkey-patching the referenced API, I noticed that Shaka Player has empty values for robustness in both videoCapabilities & audioCapabilities. When comparing this to RxPlayer, these contain values like HW_SECURE_ALL, HW_SECURE_DECODE, HW_SECURE_CRYPTO, SW_SECURE_DECODE & SW_SECURE_CRYPTO.

I also saw that RxPlayer has undocumented loadVideo options for both videoRobustnesses & audioRobustnesses. When setting these to an empty array, I was able to play content for a single time. Every second attempt ended up with a new type of error message:
EncryptedMediaError (KEY_GENERATE_REQUEST_ERROR) NotSupportedError: Cdm is nothing

Ok thanks!

Interesting, so despite announcing L1 support, it seems that they don't accept any of the widevine robustness levels...
We could try adding a supplementary undefined video and audio robustness when checking for widevine support to better handle those devices.

Every second attempt ended up with a new type of error message

Every second attempt on the same given content or just any second call to loadVideo?

We've seen an issue at the end of last year on LG TVs where playing an already-played encrypted content on the same RxPlayer instance could lead there to infinite rebuffering. We found a work-around for them, we could also try that same work-around here.


I can try creating a branch with both work-arounds. If I do, do you know how to test it on your side?

Every second attempt on the same given content or just any second call to loadVideo?

Just any second call, it doesn't matter whether it's the same content or not.

BTW, after setting RxPlayer.LogLevel = "DEBUG"; again I noticed the initial error is thrown right after this log message:
DRM: Trying to close a MediaKeySession

After some digging I ended up disabling the closeSessionsOnStop option (setting it to false), which resulted in a working player for all scenario's!

However, I'm not sure whether this is a good option to use as the documentation mentions:
This might be required by your key system implementation (most often, it is not).

I can try creating a branch with both work-arounds. If I do, do you know how to test it on your side?

That should be fine, yes.

OK I just pushed on the compat/panasonic2019 branch the two work-arounds.

This branch isn't built so you will probably want to build it before performing your tests.
Which build script to use depend on how to rely on the rx-player, you can call npm run build:all for all type of builds (do not forget to call npm install first). You can then rely on this local build of the RxPlayer, for example through npm link or yarn link commands.

OK I just pushed on the compat/panasonic2019 branch the two work-arounds.

This branch isn't built so you will probably want to build it before performing your tests. Which build script to use depend on how to rely on the rx-player, you can call npm run build:all for all type of builds (do not forget to call npm install first). You can then rely on this local build of the RxPlayer, for example through npm link or yarn link commands.

I've build the project using npm run build:all, and I do see these warnings now:
It is recommended that a robustness level be specified. Not specifying the robustness level could result in unexpected behavior in the future, potentially including failure to play.

So, the robustness setting should be working.

However, now I get these kind of warnings/errors:
EncryptedMediaError: (intermediate value).finally is not a function

Weird this seems like the code that breaks is here:

Which would mean that you are in an environment where Promise.prototype.finally does not exist...
Are you polyfilling Promises in your application?

We do polyfill Promises (using https://github.com/stefanpenner/es6-promise), but this appears to have an issue when Promise is (partially) implemented.

I've also tested the solution on a webOS 3.9, which has a native Promise implementation, but it lacks support for finally() as well. So, this device also throws the previously listed error.

We didn't have any issues with this yet, so was this added recently?

Yes that code was just added in the for now unreleased v3.30.0. I thought that finally had a higher support than that.

I may have to replace all occurences of it, I'm looking at if it can be done elegantly without needing to repeat the same boilerplate everywhere.

Yes that code was just added in the for now unreleased v3.30.0. I thought that finally had a higher support than that.

I may have to replace all occurences of it, I'm looking at if it can be done elegantly without needing to repeat the same boilerplate everywhere.

BTW, your initial changes seem to work! I've hacked the polyfill a bit in order to support finally() at all times.

Ah that's nice!

I updated the branch so it does not use finally anymore.

Also, to merge that fix, can you give me the user-agent of panasonic TVs (or a way to detect all of them)? For now the work-around is done generally for tests so cannot be merged as is.

From their documentation:

2.4 HTTP User Agent Header

All outgoing HTTP requests shall include a user agent header as specified by [HbbTV 2.0.1] chapter 7.3.2.4:

HbbTV/1.4.1 (<capabilities>; <vendorName>; <modelName>;<softwareVersion>; [< hardwareVersion>]; <familyName>; <reserved>)

where
<capabilities> is an empty string , 
<vendorName> matches Panasonic , and
<modelName> matches VIERA 2017

In order to allow service providers to differentiate between the different launch points (from broadcast or from Pana sonic Apps portal), the Panasonic HbbTV(OTT) SDK client will append following suffix at the end of this User Agent string for the latter case:

PanasonicSDK/<version>

where <version> shall be 2017 for devices conforming to this specification.

A valid example of the syntax above is
User-Agent: HbbTV/1.4.1 (;Panasonic;VIERA 2017;3.017;2b01 0003 0002-0000;) PanasonicSDK/2017

Nice, thanks!

I compared with some user-agents seen on the web and I've been more broad, catching [Pp]anasonic on the user agent (LG's WebOS made me skeptical of vendor's documentations, plain wrong in their case!) when the device is not detected as another platform.

I updated the branch to try to make it "mergable", can you test its new form and tell me if everything still works?

Nice, thanks!

I compared with some user-agents seen on the web and I've been more broad, catching [Pp]anasonic on the user agent (LG's WebOS made me skeptical of vendor's documentations, plain wrong in their case!) when the device is not detected as another platform.

I updated the branch to try to make it "mergable", can you test its new form and tell me if everything still works?

I've just completed another test round, and it's still working nicely 😄

Now that the v3.30.0 is officially released, you should have panasonic 2019 DRM support, through a stable version.

I'm closing this issue, do not hesitate to re-open it if you still have a problem