Clearkey --Error generating key request -- TypeError
Created by: jarek-vewd
Environment
-
The MPD passes the DASH-IF Conformance Tool on https://conformance.dashif.org/ -
The stream has correct Access-Control-Allow-Origin headers (CORS) -
There are no network errors such as 404s in the browser console when trying to play the stream -
The issue observed is not mentioned on https://github.com/Dash-Industry-Forum/dash.js/wiki/FAQ - [] The issue occurs in the latest reference client on http://reference.dashif.org/dash.js/ and not just on my page
- Link to playable MPD file: https://d1z81hh8vts55c.cloudfront.net/progressive/encrypted/tears_of_steel_key0_key5_ck.mpd
- Dash.js version: 3.0.0
- Browser name/version: Google Chrome 78.0.3904.97
- OS name/version: Ubuntu 16
Steps to reproduce
- Run site:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Clearkey DRM instantiation example</title>
<script src="https://reference.dashif.org/dash.js/v3.0.0/dist/dash.all.debug.js"></script>
<!--dash.all.min.js should be used in production over dash.all.debug.js
Debug files are not compressed or obfuscated making the file size much larger compared with dash.all.min.js-->
<!--<script src="http://reference.dashif.org/dash.js/v3.0.0/dist/dash.all.debug.js"></script>-->
<script class="code">
function init() {
const protData = {
"org.w3.clearkey": {
"clearkeys": {
"MDAwMDAwMDAwMDAwMDAwMA": "Pwoz80CYueIrwHjgobXoVA",
"MDAwMDAwMDAwMDAwMDAwNQ": "msMDbgSsnSvpRu1iQFFJvA"
}
}
};
var video,
player,
url = "https://d1z81hh8vts55c.cloudfront.net/progressive/encrypted/tears_of_steel_key0_key5_ck.mpd";
video = document.querySelector("video");
player = dashjs.MediaPlayer().create();
player.initialize(video, url, true);
player.setProtectionData(protData);
}
</script>
<style>
video {
width: 640px;
height: 360px;
}
</style>
</head>
<body>
<div >
<video controls="true">
</video>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
init();
});
</script>
</body>
</html>
2, Reload the page until error in devtools will occurs:
[142][Stream] DRM: unable to create session! --Error generating key request -- TypeError
Reproduction rate about 15%
Observed behaviour
This stream contains encrypted audio and video. Browser send two needKey messages to the application. The problem will not occur when these messages are sent one after another in a row.
The problem starts when the second needKey event will arrive after the end of the first one and after the execution of the event:
onKeySystemSelected = function onKeySystemSelected(event)
Becuase this method cause keySystem variable to be set up, so when the second needKey occurs, method:
function selectKeySystem(supportedKS, fromManifest)
executes:
createKeySession(supportedKS[ksIdx].initData, supportedKS[ksIdx].cdmData);
This is invalid because we should send an initData from peendingNeedKeyData after
TextEncoder().encode(JSON.stringify(initData));
Like in the block of the code:
if (keySystem === pendingNeedKeyData[i][ksIdx].ks) {
// For Clearkey: if parameters for generating init data was provided by the user, use them for generating
// initData and overwrite possible initData indicated in encrypted event (EME)
if (protectionKeyController.isClearKey(keySystem) && protData && protData.hasOwnProperty('clearkeys')) {
var initData = { kids: Object.keys(protData.clearkeys) };
pendingNeedKeyData[i][ksIdx].initData = new TextEncoder().encode(JSON.stringify(initData));
}
if (pendingNeedKeyData[i][ksIdx].sessionId) {
// Load MediaKeySession with sessionId
loadKeySession(pendingNeedKeyData[i][ksIdx].sessionId, pendingNeedKeyData[i][ksIdx].initData);
} else if (pendingNeedKeyData[i][ksIdx].initData !== null) {
// Create new MediaKeySession with initData
createKeySession(pendingNeedKeyData[i][ksIdx].initData, pendingNeedKeyData[i][ksIdx].cdmData);
}
break;
}
If we will do this the second createKeySession will use init data which was provided by the user via: player.setProtectionData(protData); instead of sending the wrong one from pssh.