Closed cjw1115 closed 2 years ago
Hi @swenkeratmicrosoft , could you help me about this?
I have a PlayReady DASH content and it hosted on my website(by default, it will be a persistent license), Edge browser can play it. But when I use my modified chromium: If I hardcode CDM session to Persistent, it will work; If I hardcode CDM session to Temporary it will fail with error code 0x80704005.
So I guess Edge did something internally to handle it. That's why I ask this quesiton.
Thanks!
Hi @cjw1115,
Edge doesn't do anything special to handle this scenario. It is the expectation and design of the EME interface that it's the responsibility of the caller to know, preemptively (before it calls generateRequest), whether the server is going to respond with a temporary or persistent license.
Furthermore, you can't create a license acquisition challenge in a persistent session and then process the response in a temporary session. The call to update must be on the same session as generateRequest.
In order to do what you're suggesting (determining the license type from the response), you'd not only have to create two sessions (one temporary and one persistent), you'd also need to call generateRequest on both, send two separate license acquisition requests to the server, get two responses, then throw away one of the responses. Since production-class license acquisition servers generally prevent you from acquiring unnecessary licenses, they will likely reject one of those requests, and if the other request's response doesn't have a license that matches the session from which its request was created, you're back where you started. In essence, creating two sessions doesn't realistically help you.
You shouldn't be hard-coding the CDM session to anything. You should be taking it in as input from the website/application, and the latter must be implemented to pass the right value based on what type of license it knows the server is going to return. If the website/application doesn't know that information a-priori, then that's a design flaw in the caller - they are failing to use the EME interfaces as designed.
Does that make sense? I hope that's helpful, but feel free to ask for further clarification. Happy to help.
-Sam Wenker Microsoft PlayReady Architect
Hi @swenkeratmicrosoft, Thanks for your quick reply.
Yes, to set sessionType is responsibility of caller. Generally, browser just need to follow web app's settings in requestMediaKeySystem.
The strange thing is that, the same web app, same configurations to browser by EME interface. Edge works! That's why I guess Edge may have special processing;
For second point, I did what you said earlier, create two sessions together, and create to generateRequest together. For update, code is here,.
virtual HRESULT STDMETHODCALLTYPE Update(
/* [size_is][in] */ __RPC__in_ecount_full(responseSize) const BYTE* response,
/* [in] */ DWORD responseSize)
{
HRESULT hr = m_majorSession->Update(response, responseSize);
if (hr == (HRESULT)0x80704005)
{
hr = m_backupSession->Update(response, responseSize);
if (hr == S_OK)
{
m_useBackup = true;
m_sessionCallbacks->KeyStatusChanged();
}
}
return hr;
}
but it not totally work. After m_majorSession->Update, if it failed, MediaEngineProtectionManager::EndEnableContent will be called and MF_MEDIA_ENGINE_EVENT_ERROR event be notified.
That why I ask how to distinguish license persistent type, if license persistent type is temporary, I will just call temporary session's update() interface, and drop persistent session, vice-versa.
BTW, I found there are some PlayReady drmxmr.h definition on github. I tried to use them to parse license response. but looks thay are not match. For XMR, Does this a public standard or Microsoft internal? can I got some API or docs?
Thanks!
Hi @cjw1115,
Why are you creating two sessions in the first place? Edge absolutely doesn't. Or is your website doing so?
-Sam Wenker Microsoft PlayReady Architect
Since I'm not very familiar chromium's code, so I want to create them in same place. Make things easier.
May be I should try to create them one by one, if first one update failed, I should reinitialize it and create another session.
Hi @cjw1115,
I'm not sure what you mean by "create them in the same place".
When the website calls createSession, you should create a single session of the same type as the website requested.
Or am I missing something?
-Sam Wenker Microsoft PlayReady Architect
Hi @cjw1115,
I'm not sure what you mean by "".
When the website calls createSession, you should create a single session of the same type as the website requested.
Or am I missing something?
-Sam Wenker
Microsoft PlayReady Architect
Yes, chromium will create session on MF CDM with the website requested session type, if website ignore the session type,it will be temporary by default.
When chromium create session on CDM,
This is meaning of "create them in the same place", it's not too much elegant😀
Hi @cjw1115,
My question is: Why are you doing step 1 at all? What is the purpose of creating a backup session?
-Sam Wenker Microsoft PlayReady Architect
Hi @swenkeratmicrosoft,
My purpose is: I want to play PlayReady encrypted content even if web app didn't set a session type explicitly.
I created a web app use DASH JS to play a PlayReady content, and I didn't set sessionType in navigator.requestMediaKeySystemAccess, DASH JS set it with a default Temporary session type. but my content's license is persistent license by default.
Then Edge can play it successfully. It's strange, a persistent license with temporary session type, expected result should be playback failure. so I have to guess Edge have some special processing here.
For this purpose, I have one walkaround.
protectedMediaEngine->SetContentProtectionManager(m_protectionManager.get());
For step 5, I found if I call it before update session with license(step 4). the BeginEnableContent
will be called. then if update()
of major session failed in step 4, the 'EndEnableContent' will be called. and an error notified. I have no chance to call update() of backup session.
That's why I ask if there are some API or specs can detect license persistent type from a base64 string of XMR.
Thanks!
Hi @cjw1115,
Ok, now I understand what you're saying.
The EME spec/APIs are designed to not allow you to playback with a persistent license with temporary session type.
Per specification https://www.w3.org/TR/encrypted-media/#dom-mediakeysession-update
Refer to the section starting with "Process sanitized response, following the stipulation for the first matching condition from the following list:". The spec explicitly says that update is supposed to fail with TypeError in this case.
If you implement update to allow this as you describe, you are in direct violation of the EME specification. If Edge is allowing this behavior, it is a bug in Edge which we will fix. I'd like your help to determine if there's an Edge bug here, if that's all right?
Regardless of the result of the above Edge investigation:
I hope this helps, and thanks for continuing to work with me on this issue.
-Sam Wenker Microsoft PlayReady Architect
Hi @swenkeratmicrosoft, Thank you for such detailed reply. It's helpful! I used key system "com.microsoft.playready" in my webapp.
For my persistent license, I tried below combinations on Edge:
Edge works as your description. it has no bug here.
Thanks again. the issue can be closed.
I created a MF_MEDIAKEYSESSION_TYPE_TEMPORARY session, but I get a persistent PlayReady license after genereateRequest. Then I try to call IMFContentDecryptionModuleSession::Update, it will told me session type are not match.
Here is data format pass into IMFContentDecryptionModuleSession::Update(),
the major license info is a base64 encoded. And it used XMR format. I didn't found any standard or document about XMR format. I can only get brief structure.
My question is how can I know the license is persistent or just temporary?
Because I want to create two sessions, one is temporary, and another one is persistent.
If I can know the response license type, then I can use correct one session to call IMFContentDecryptionModuleSession::Update
Thanks!