Orange-OpenSource / hasplayer.js

Http Adaptive Streaming javascript player based on HTML5 premium extensions (MSE/EME)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Chrome with widevine DRM Error: Media is encrypted and no valid key is available

ivocarminati opened this issue · comments

Hi all,

I have a problem streaming protected content using widevine DRM on the latest version of Chrome (61.0.3163.79), while with all the other browsers all is working fine.
When I try to stream any content, randomly I receive an error: "Media is encrypted and no valid key is available". After some stream attempts the player starts streaming correctly but I cannot understand why it has this behavior.
I've notice that all the time the player raises this error in the code it passes through a "waitingforkey" event in the ProtectionModel_21Jan2015.js file, but I don't know why. I've just checked and the DRM is correctly sending to the player the license key, but it seems that something is going wrong with decryption keys.
Can anyone help me solving this issue please?

Thanks.

Hi,
This error is raised if "waitingforkey" event is raised once the license has been successfully received and attached to the MediaKey session and once the "usable" state for this license has been raised.
Then that means the received decryption key in the license is not the good to decrypt the content.

Hi @bbert ,

could you please help me with more details? How can I solve? What can I check in order to be sure that I'm doing all right and fix this issue?

Thanks a lot and best regards

Hi @ivocarminati,
Can you provide access to any stream so that we can test and confirm the behavior?

Hi @bbert,

unfortunately I cannot provide you any stream content for policy reasons.
What I see is that the player, after the load() function, many times go in waitingForKey event, but not always. I can't understand why sometimes all is working fine and sometimes not with the same stream content. I checked and the widevine DRM is correctly sending the license also when I get the error. It seems to be an error related to timeout. In fact, if I receive the error and I reinitialize all the player flow, all works correctly after 1 or 2 attempts. For this reason I think the logic that drive me in error is contained in hasplayer library, but I cannot understand what.

Hi @ivocarminati,
What you can do is to install "EME Call and Event Logger" plugin in chrome, and then send us all the logs you get in this plugin.

Hi @bbert ,

thanks for your fast answers. I'll provide you the log as soon as possible.

In the meantime I need to advise you about a change I made in the hasplayer code into the CommonEncryption.js module in order to store the device id into the CDM.

I've changed the line (CommonEncryption.js module)
audioCapabilities, videoCapabilities, "optional", (sessionType === "temporary") ? "optional" : "required", [sessionType])];

into this:
audioCapabilities, videoCapabilities, "optional", "required", [sessionType])];

forcing the persistentState set to required.

Could the problem be caused by this change?
Thanks a lot for your help.

Hi @bbert ,

in attach you can see the EME log thanks to your suggestion.
I hope with this log you can help me to resolve the issue.

Thanks
EMELogFile.txt

@ivocarminati We encountered something similar related to persistentState = required. Please see our bug report here https://bugs.chromium.org/p/chromium/issues/detail?id=690389#c4 Does your playback starts if you seek forward?

Hi @bbert ,

I've tried but also seeking forward the problem appears.
So, isn't there a solution to this problem with persistenState = required?

Hi @dsilhavy, @bbert

do you know a solution / workaround that solve the issue?

Thanks in advance and best regards.

Hi,

I've the same issue when I set the persistentState to required
Did you have any idea how to resolve it?

Thanks in advance,
Regards,
Claudio

Hi @bbert, @dsilhavy,

I've also another problem during the stream of linear content: sometimes I get an error:

MEDIA_KEYSYSERR_ACCESS_DENIED = "No KeySystem/CDM available"

Why? Which is the possible cause?
Could you help me with this problem?
I cannot find a solution and I fear it is caused by the same root cause of the previous problem.

Thanks and best regards.

Which browser?
It can be due to insecure origin.
Can you provide conditions (browser, http/s, ...) and logs?

Hi @bbert ,

the browser affected are always the same: Chrome and Mozilla Firefox.
The "Access-Control-Allow-Origin" in the response headers of widevine calls is correctly set to the right domain.
In attachment you can find some EME logs.
I hope you can help me finding a solution.

Thanks in advance @bbert
EMELogFile.txt

@ivocarminati Be aware of recent changes to Chrome which require you to run your application in a secure context (https). Calling EME functions in an application from http context (despite localhost I think) will lead to problems.

Hi @dsilhavy ,

I'm already running my application in a secure context https :-(
For this reason I cannot undestand the root cause of these problems.
The DRM is correctly sending me the right license but hasplayer seems to has some problems with sessionType = "persistent-license" and I need to solve this issue as soon as possible :(

Hi @dsilhavy and @bbert,

could the problem be related to the warning I see in browser console "It is recommended that a robustness level be specified. Not specifying the robustness level could result in unexpected behavior, potentially including failure to play"???
In any case, how can I solve this warning, too?

Hi @ivocarminati,
I had a look to your logs but it was huge, so difficult to locate the issue.
Can you send only part of the logs when it fails?
Also can you send the logs of the player?
On my side I am not able to test with sessionType = "persistent-license" since I do not have access to a CDM with persistence.
For robustness levels, you can try by specifying them in protData (see README and jsdoc).

Hi @bbert, @dsilhavy ,

here attached the log of hasplayer in case of error.
I hope this helps you find a solution for us.
I do not know what to do more.

hasplayer.log

Hello, @bbert do you have any update on this topic? I'm experiencing the same issue.

Hello,
If we take a look at the last logs we got from @ivocarminati, we can notice this:

[11:53:02.886][DRM] Key statuses changed. statuses = [object Object] 
[11:53:02.886][DRM][PM_21Jan2015] status = usable for KID [0x3d,0x22,0x5b,0x93,0x48,0x18,0x49,0x8f,0x9d,0x54,0x12,0xc6,0x30,0x9f,0x9c,0xee] 
[11:53:02.889][DRM][PM_21Jan2015] 'waitingforkey' event 
[11:53:02.890][Error] Code: MEDIA_ERR_ENCRYPTED, Message: Media is encrypted and no valid key is available, Data: null 

As I previously said, the player receives a license for the content (based on KID extracted from ProtectionHeader, but the received decryption key seems not to be valid/appropriate for the current content, since the CDM raises afterwards a 'waitingforkey' event after.

Question:
If you disable the 'waitingforkey' event listener (comment line 216 in ProtectionModel_21Jan2015.js), is the content decrypted and played?

// videoElement.addEventListener("waitingforkey", eventHandler);

Hello. yes, we tried but the outcome is that no playback is possible (player stay as it is)
We verified vs DRM and everything seems fine on their side, we are receiving the right license, so most probably it's something that is happening before the waitingforKey event is raised.

Hello
If you notice no playback then it confirms that the content can not be decrypted with the received key.
That's why the 'waitingforkey' event is rightly raised.

As far as I know, the only thing I can accuse is the licenser.

Have/can you check if KID indicated by CDM (status = usable for KID [...]) is the same as the KID included in ProtectionHeader, after conversion from little-endian to big-endian.

Hello Bert, we checked and they are exactly the same. We made further analysis. Accoriding to what depicted in https://www.html5rocks.com/en/tutorials/eme/basics/ "The recommended flow is to negotiate MediaKeys first, using MediaKeysSystemAccess.getConfiguration() to find out the negotiated configuration"
in Hasplayer code such call is performed any time that the mediaElement identify an encrypted item and raises the event EncryptedEvent. In other players (i.e shaka) this action is performed only once. could you tell us why this is happening?
We noticed that something goes wrong in here (at least from EME perspective) because I have eme log to demonstrate this. UpdateCall 14:49:20:856
target:
MediaKeySession {
sessionId: 521464AA3640B2CAEE45ED23E40ADA5F
expiration: null
keyStatuses: Array{}
}
returned: Promise{}

such promise is not returned when we are getting such error and this is what we have later:

KeyStatusesChangeEvent 1:8:53:886
event:
Event {
isTrusted: true
}
target:
MediaKeySession {
sessionId: 521464AA3640B2CAEE45ED23E40ADA5F
expiration: null
keyStatuses: [
keyId:
80,135,228,48,221,35,69,10,189,78,248,63,6,249,219,132
status: usable]
}

keyID is the same in both ok / ko status but the expiration param in case of KO si null, instead it has value for the OK scenario. If you want I can share with you the full log.

Yes please send me the full EME log

Ok, I'm going to send you the full eme log in private email (your@orange.com). is it fine?

Hi @bbert ,

I've just tried to update the hasplayer in my project to the latest version available (v. 1.14) and I have problems to communicating with the DRM server (widevine). I need to know how to insert custom data into the request payload, because now the DRM responds with an http 500 error code (hasplayer error: "License request failed").
Is there an API in order to add this custom data?

Thanks in advance and best regards.
Ivo

Hi @bbert ,

I add some details to my last question.
In my project I need to pass the customData below into the request payload to Widevine:

kid=guid2Str(KID)
deviceAppVersion=1.1
lang=spa

Attached you can find the function I am using for building the stream object that is passed to the mediaPlayer.load(stream) function.
I hope you can help me to understand how to pass those data correctly with the latest version of hasplayer.

Thanks in advance.
Ivo

stream_object.txt

Hi,
Since version 1.4.0 you don't need anymore to provide pssh in input protectionData.
A default pssh for Widevine is automatically generated with KID extracted from smooth manifest's protection header field.

Also I am not convinced you can safely modify the license request payload since you will then corrupt it.