--- a/encrypted-media/encrypted-media.html Mon Apr 21 14:13:13 2014 -0700
+++ b/encrypted-media/encrypted-media.html Mon Apr 21 15:34:58 2014 -0700
@@ -322,7 +322,6 @@
<pre class="idl">
enum <dfn id="dom-mediawaitingfor">MediaWaitingFor</dfn> { "<dfn id="dom-waitingfornone">none</dfn>", "<dfn id="dom-waitingfordata">data</dfn>", "<dfn id="dom-waitingforkey">key</dfn>" };
-
partial interface <dfn id="dom-htmlmediaelement">HTMLMediaElement</dfn> {
// Encrypted Media
readonly attribute <a href="#dom-mediakeys">MediaKeys</a> <a href="#dom-attrmediakeys">mediaKeys</a>;
@@ -333,10 +332,11 @@
readonly attribute <a href="#dom-mediawaitingfor">MediaWaitingFor</a> <a href="#dom-waitingfor">waitingFor</a>;
};
+enum SessionType { "temporary", "persistent" };
interface <dfn id="dom-mediakeys">MediaKeys</dfn> {
readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
- Promise<<a href="#dom-mediakeysession">MediaKeySession</a>> <a href="#dom-createsession">createSession</a>(DOMString initDataType, Uint8Array initData);
+ Promise<<a href="#dom-mediakeysession">MediaKeySession</a>> <a href="#dom-createsession">createSession</a>(DOMString initDataType, Uint8Array initData, optional SessionType sessionType = "temporary");
Promise<<a href="#dom-mediakeysession">MediaKeySession</a>> <a href="#dom-loadsession">loadSession</a>(DOMString sessionId);
static Promise<<a href="#dom-mediakeys">MediaKeys</a>> <a href="#dom-create">create</a>(DOMString <a href="#key-system">keySystem</a>)
@@ -451,7 +451,7 @@
<p>The <dfn id="dom-keysystem"><code>keySystem</code></dfn> attribute identifies the <a href="#key-system">Key System</a> being used.</p>
- <p>The <dfn id="dom-createsession"><code>createSession(initDataType, initData)</code></dfn> method must run the following steps:</p>
+ <p>The <dfn id="dom-createsession"><code>createSession(initDataType, initData, sessionType)</code></dfn> method must run the following steps:</p>
<p class="non-normative">Note: The contents of <var title="true">initData</var> are container-specific <a href="#initialization-data">Initialization Data</a>.
<var title="true">initDataType</var> is the <a href="#initialization-data-type">initialization data type</a> that indicates how to interpret <var title="true">initData</var>.
</p>
@@ -463,6 +463,7 @@
<li><p>If <var title="true">initDataType</var> is an empty string, return a promise rejected with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-InvalidAccessError">"InvalidAccessError"</a></code> and that has the message "The initDataType parameter is empty."</p></li>
<li><p>If <var title="true">initData</var> is an empty array, return a promise rejected with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is<code><a href="#dfn-InvalidAccessError">"InvalidAccessError"</a></code> and that has the message "The initData parameter is empty."</p></li>
<li><p>If <var title="true">initDataType</var> is not an <a href="#initialization-data-type">initialization data type</a> supported by the <a href="#cdm">content decryption module</a> corresponding to the <code><a href="#dom-keysystem">keySystem</a></code>, return a promise rejected with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code> and that has the message "The initialization data type <var title="true">initDataType</var> is not supported by the key system."</p></li>
+ <li><p>If <var title="true">sessionType</var> is not supported by the <a href="#cdm">content decryption module</a> corresponding to the <code><a href="#dom-keysystem">keySystem</a></code>, return a promise rejected with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code> and that has the message "<var title="true">sessionType</var> sessions are not supported by the key system."</p></li>
<li><p>Let <var>promise</var> be a new promise.</p></li>
<li>
<p>Run the following steps asynchronously:</p>
@@ -478,7 +479,10 @@
<p>If a message exchange <span class="non-normative">(e.g. a license request)</span> is required:</p>
<ol>
<li>
-<p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using the <var title="true">initData</var>.</p>
+<p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using the <var title="true">initData</var> and <var title="true">sessionType</var>.</p>
+ <p>If <var title="true">sessionType</var> is <code>"temporary"</code>, the request is for a temporary non-persisted license.
+ If <var title="true">sessionType</var> is <code>"persistent"</code>, the request is for a persistable license.</p>
+ <p class="non-normative">Note: The license server may reject the requested type. It should not issue a different type.</p>
<p><var title="true">cdm</var> must not use any stream-specific data, including <a href="http://www.w3.org/TR/html5/embedded-content-0.html#media-data">media data</a>, not provided via the <var title="true">initData</var>.</p>
</li>
<li><p>If the <var title="true">initData</var> indicates a default URL relevant to <var title="true">keySystem</var>, let <var title="true">default URL</var> be that URL.</p></li>
@@ -493,6 +497,7 @@
<li><p>Set the <code><a href="#dom-error">error</a></code> attribute to null.</p></li>
<li><p>Set the <code><a href="#dom-sessionkeysystem">keySystem</a></code> attribute to the value of the <code><a href="#dom-mediakeys">MediaKeys</a></code> object's <code><a href="#dom-keysystem">keySystem</a></code> attribute.</p></li>
<li><p>Set the <code><a href="#dom-sessionid">sessionId</a></code> attribute to <var title="true">session ID</var>.</p></li>
+ <li><p>Let the session type be <var title="true">sessionType</var>.</p></li>
</ol>
</li>
<li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is the appropriate <a href="#mediakeyerror-names">error name</a> and that has an appropriate message.</p></li>
@@ -537,6 +542,7 @@
<li><p>Set the <code><a href="#dom-error">error</a></code> attribute to null.</p></li>
<li><p>Set the <code><a href="#dom-sessionkeysystem">keySystem</a></code> attribute to the value of the <code><a href="#dom-mediakeys">MediaKeys</a></code> object's <code><a href="#dom-keysystem">keySystem</a></code> attribute.</p></li>
<li><p>Set the <code><a href="#dom-sessionid">sessionId</a></code> attribute to <var title="true">sessionId</var>.</p></li>
+ <li><p>Let the session type be <code>"persistent"</code>.</p></li>
</ol>
</li>
<li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is the appropriate <a href="#mediakeyerror-names">error name</a> and that has an appropriate message.</p></li>
@@ -611,7 +617,16 @@
<p>Use the <var title="true">cdm</var> to execute the following steps:</p>
<ol>
<li>
-<p>Process <var title="true">response</var>.</p>
+<p>Process <var title="true">response</var></p>
+ <p>If <var title="true">response</var> contains keys, a license, or similar data, follow the stipulation for the first matching condition from the following list:</p>
+ <dl class="switch">
+ <dt>If <var title="true">sessionType</var> is <code>"temporary"</code> and the license does not specify it should be stored</dt>
+ <dd>Do not store the license or other data contained in <var title="true">response</var>.</dd>
+ <dt>If <var title="true">sessionType</var> is <code>"persistent"</code> and the license permits storage</dt>
+ <dd>Store the license or other data contained in <var title="true">response</var>.</dd>
+ <dt>Otherwise</dt>
+ <dd>Fail with an appropriate <a href="#mediakeyerror-names">error name</a> and message.</dd>
+ </dl>
<p class="non-normative">Note: When <var title="true">response</var> contains key(s) and/or related data, <var title="true">cdm</var> will likely cache the key and related data indexed by key ID.</p>
<p class="non-normative">Note: The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p>
<p class="non-normative">Note: Keys from different sessions should be cached independently such that closing one session does not affect keys in other sessions, even if they have overlapping key IDs.</p>
@@ -694,6 +709,7 @@
The existing MediaKeys object cannot be removed.<br>
The key system <em>name</em> is not supported.<br>
The initialization data type <em>type</em> is not supported by the key system.<br>
+ <em>type</em> sessions are not supported by the key system.<br>
The operation is not supported by the key system.
</td>
</tr>
@@ -1074,6 +1090,7 @@
<p class="non-normative">The CDM may close a session at any point, such as in response to a <code><a href="#dom-release">release()</a></code> call, when the session is no longer needed, or when resources are lost.
Keys in other sessions should be unaffected, even if they have overlapping key IDs.
</p>
+ <p>If <var title="true">sessionType</var> is <code>"persistent"</code>, the CDM must have cleared all stored session data associated with the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p>
<p>The following steps are run:</p>
<ol>
<li><p>Let <var>promise</var> be the <code><a href="#dom-close">close</a></code> attribute of the associated <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
@@ -1494,6 +1511,92 @@
<video id="v" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)"></video></pre>
</div>
+ <h3 id="example-stored-license" class="exampleheader">8.5. Stored License</h3>
+ <p class="exampledescription">This example requests a persistent license for future use and stores it. It also provides functions for later retrieving the license and for destroying it.</p>
+
+ <div class="example">
+ <pre class="code">
+<script>
+ var keySystem;
+ var licenseUrl;
+ var mediaKeys;
+
+ // See the previous examples for implementations of these functions.
+ function selectKeySystem() { ... }
+ function sendMessage(message, keySession) { ... }
+ function handleMessage(event) { ... }
+ function handleError(event) { ... }
+
+ // Called if the application does not have a stored sessionId for the media resource.
+ function createSession(mediaKeys, initDataType, initData) {
+ mediaKeys.<a href="#dom-createsession">createSession</a>(initDataType, initData, "persistent").then(
+ function(keySession) {
+ keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
+ keySession.addEventListener("<a href="#dom-eventerror">error</a>", handleError, false);
+ keySession.close.then(
+ console.log.bind(console, "Session closed")
+ );
+ // Store keySession.<a href="#dom-sessionid">sessionId</a> in the application.
+ }
+ ).catch(
+ console.error.bind(console, "Unable to create or initialize a persistable key session")
+ );
+ }
+
+ // Called if the application has a stored sessionId for the media resource.
+ function loadStoredSession(mediaKeys, sessionId) {
+ mediaKeys.<a href="#dom-loadsession">loadSession</a>(sessionId).then(
+ function(keySession) {
+ if (!keySession) {
+ console.error("No stored session with the ID " + sessionId + " was found.");
+ return;
+ }
+ keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
+ keySession.addEventListener("<a href="#dom-eventerror">error</a>", handleError, false);
+ keySession.close.then(
+ console.log.bind(console, "Session closed")
+ );
+ }
+ ).catch(
+ console.error.bind(console, "Unable to load or initialize the stored session with the ID " + sessionId)
+ );
+ }
+
+ // Called when the application wants to remove the license for the media resource.
+ removeStoredSession(keySession) {
+ keySession.<a href="#dom-release">release</a>().catch(
+ console.error.bind(console, "Unable to release the session")
+ );
+ }
+
+ // This replaces the implementation in the previous example.
+ function handleMessageResponse(keySession, response) {
+ var license = new Uint8Array(response);
+ keySession.<a href="#dom-update">update</a>(license).then(
+ function() {
+ // If this was the last required message from the server, the license is
+ // now stored. Update the application state as appropriate.
+ }
+ ).catch(
+ console.error.bind(console, "update() failed")
+ );
+ }
+
+ selectKeySystem();
+ <a href="#dom-mediakeys">MediaKeys</a>.<a href="#dom-create">create</a>(keySystem).then(
+ function(createdMediaKeys) {
+ mediaKeys = createdMediaKeys;
+ var video = document.getElementById("v");
+ return video.<a href="#dom-setmediakeys">setMediaKeys</a>(mediaKeys);
+ }
+ ).catch(
+ console.error.bind(console, "Unable to create or use new MediaKeys")
+ );
+</script>
+
+<video id="v" src="foo.webm" autoplay></video></pre>
+ </div>
+
<h2 id="revision-history">9. Revision History</h2>
<table>
--- a/encrypted-media/encrypted-media.xml Mon Apr 21 14:13:13 2014 -0700
+++ b/encrypted-media/encrypted-media.xml Mon Apr 21 15:34:58 2014 -0700
@@ -319,7 +319,6 @@
<pre class="idl">
enum <precodedfn>MediaWaitingFor</precodedfn> { "<precodedfn prefix="waitingfor">none</precodedfn>", "<precodedfn prefix="waitingfor">data</precodedfn>", "<precodedfn prefix="waitingfor">key</precodedfn>" };
-
partial interface <precodedfn>HTMLMediaElement</precodedfn> {
// Encrypted Media
readonly attribute <precoderef>MediaKeys</precoderef> <precoderef prefix="attr">mediaKeys</precoderef>;
@@ -330,10 +329,11 @@
readonly attribute <precoderef>MediaWaitingFor</precoderef> <precoderef>waitingFor</precoderef>;
};
+enum SessionType { "temporary", "persistent" };
interface <precodedfn>MediaKeys</precodedfn> {
readonly attribute DOMString <precoderef>keySystem</precoderef>;
- Promise<<precoderef>MediaKeySession</precoderef>> <premethodref>createSession</premethodref>(DOMString initDataType, Uint8Array initData);
+ Promise<<precoderef>MediaKeySession</precoderef>> <premethodref>createSession</premethodref>(DOMString initDataType, Uint8Array initData, optional SessionType sessionType = "temporary");
Promise<<precoderef>MediaKeySession</precoderef>> <premethodref>loadSession</premethodref>(DOMString sessionId);
static Promise<<precoderef>MediaKeys</precoderef>> <premethodref>create</premethodref>(DOMString <a href="#key-system">keySystem</a>)
@@ -438,7 +438,7 @@
<p>The <codedfn>keySystem</codedfn> attribute identifies the <a href="#key-system">Key System</a> being used.</p>
- <p>The <methoddfn name="createSession">createSession(<var title="true">initDataType</var>, <var title="true">initData</var>)</methoddfn> method must run the following steps:</p>
+ <p>The <methoddfn name="createSession">createSession(<var title="true">initDataType</var>, <var title="true">initData</var>, <var title="true">sessionType</var>)</methoddfn> method must run the following steps:</p>
<p class="non-normative">Note: The contents of <var title="true">initData</var> are container-specific <a href="#initialization-data">Initialization Data</a>.
<var title="true">initDataType</var> is the <a href="#initialization-data-type">initialization data type</a> that indicates how to interpret <var title="true">initData</var>.
</p>
@@ -450,6 +450,7 @@
<li><p>If <var title="true">initDataType</var> is an empty string, return a promise rejected with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-InvalidAccessError">"InvalidAccessError"</a></code> and that has the message "The initDataType parameter is empty."</p></li>
<li><p>If <var title="true">initData</var> is an empty array, return a promise rejected with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is<code><a href="#dfn-InvalidAccessError">"InvalidAccessError"</a></code> and that has the message "The initData parameter is empty."</p></li>
<li><p>If <var title="true">initDataType</var> is not an <a href="#initialization-data-type">initialization data type</a> supported by the <a href="#cdm">content decryption module</a> corresponding to the <coderef>keySystem</coderef>, return a promise rejected with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code> and that has the message "The initialization data type <var title="true">initDataType</var> is not supported by the key system."</p></li>
+ <li><p>If <var title="true">sessionType</var> is not supported by the <a href="#cdm">content decryption module</a> corresponding to the <coderef>keySystem</coderef>, return a promise rejected with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code> and that has the message "<var title="true">sessionType</var> sessions are not supported by the key system."</p></li>
<li><p>Let <var>promise</var> be a new promise.</p></li>
<li><p>Run the following steps asynchronously:</p>
<ol>
@@ -461,7 +462,10 @@
<li><p>Process the <var title="true">initData</var>, interpreting it per <var title="true">initDataType</var>.</p></li>
<li><p>If a message exchange <span class="non-normative">(e.g. a license request)</span> is required:</p>
<ol>
- <li><p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using the <var title="true">initData</var>.</p>
+ <li><p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using the <var title="true">initData</var> and <var title="true">sessionType</var>.</p>
+ <p>If <var title="true">sessionType</var> is <code>"temporary"</code>, the request is for a temporary non-persisted license.
+ If <var title="true">sessionType</var> is <code>"persistent"</code>, the request is for a persistable license.</p>
+ <p class="non-normative">Note: The license server may reject the requested type. It should not issue a different type.</p>
<p><var title="true">cdm</var> must not use any stream-specific data, including <videoanchor name="media-data">media data</videoanchor>, not provided via the <var title="true">initData</var>.</p>
</li>
<li><p>If the <var title="true">initData</var> indicates a default URL relevant to <var title="true">keySystem</var>, let <var title="true">default URL</var> be that URL.</p></li>
@@ -475,6 +479,7 @@
<li><p>Set the <coderef>error</coderef> attribute to null.</p></li>
<li><p>Set the <coderef prefix="session">keySystem</coderef> attribute to the value of the <coderef>MediaKeys</coderef> object's <coderef>keySystem</coderef> attribute.</p></li>
<li><p>Set the <coderef>sessionId</coderef> attribute to <var title="true">session ID</var>.</p></li>
+ <li><p>Let the session type be <var title="true">sessionType</var>.</p></li>
</ol>
</li>
<li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is the appropriate <a href="#mediakeyerror-names">error name</a> and that has an appropriate message.</p></li>
@@ -515,6 +520,7 @@
<li><p>Set the <coderef>error</coderef> attribute to null.</p></li>
<li><p>Set the <coderef prefix="session">keySystem</coderef> attribute to the value of the <coderef>MediaKeys</coderef> object's <coderef>keySystem</coderef> attribute.</p></li>
<li><p>Set the <coderef>sessionId</coderef> attribute to <var title="true">sessionId</var>.</p></li>
+ <li><p>Let the session type be <code>"persistent"</code>.</p></li>
</ol>
</li>
<li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is the appropriate <a href="#mediakeyerror-names">error name</a> and that has an appropriate message.</p></li>
@@ -583,7 +589,16 @@
<li><p>Let <var title="true">destination URL</var> be null.</p></li>
<li><p>Use the <var title="true">cdm</var> to execute the following steps:</p>
<ol>
- <li><p>Process <var title="true">response</var>.</p>
+ <li><p>Process <var title="true">response</var></p>
+ <p>If <var title="true">response</var> contains keys, a license, or similar data, follow the stipulation for the first matching condition from the following list:</p>
+ <dl class="switch">
+ <dt>If <var title="true">sessionType</var> is <code>"temporary"</code> and the license does not specify it should be stored</dt>
+ <dd>Do not store the license or other data contained in <var title="true">response</var>.</dd>
+ <dt>If <var title="true">sessionType</var> is <code>"persistent"</code> and the license permits storage</dt>
+ <dd>Store the license or other data contained in <var title="true">response</var>.</dd>
+ <dt>Otherwise</dt>
+ <dd>Fail with an appropriate <a href="#mediakeyerror-names">error name</a> and message.</dd>
+ </dl>
<p class="non-normative">Note: When <var title="true">response</var> contains key(s) and/or related data, <var title="true">cdm</var> will likely cache the key and related data indexed by key ID.</p>
<p class="non-normative">Note: The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p>
<p class="non-normative">Note: Keys from different sessions should be cached independently such that closing one session does not affect keys in other sessions, even if they have overlapping key IDs.</p>
@@ -663,6 +678,7 @@
The existing MediaKeys object cannot be removed.<br/>
The key system <em>name</em> is not supported.<br/>
The initialization data type <em>type</em> is not supported by the key system.<br/>
+ <em>type</em> sessions are not supported by the key system.<br/>
The operation is not supported by the key system.
</td>
</tr>
@@ -1019,6 +1035,7 @@
<p class="non-normative">The CDM may close a session at any point, such as in response to a <methodref>release</methodref> call, when the session is no longer needed, or when resources are lost.
Keys in other sessions should be unaffected, even if they have overlapping key IDs.
</p>
+ <p>If <var title="true">sessionType</var> is <code>"persistent"</code>, the CDM must have cleared all stored session data associated with the <coderef>MediaKeySession</coderef> object.</p>
<p>The following steps are run:</p>
<ol>
<li><p>Let <var>promise</var> be the <coderef>close</coderef> attribute of the associated <coderef>MediaKeySession</coderef> object.</p></li>
@@ -1437,6 +1454,92 @@
<video id="v" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)"></video></pre>
</div>
+ <h3 id="example-stored-license" class="exampleheader">8.5. Stored License</h3>
+ <p class="exampledescription">This example requests a persistent license for future use and stores it. It also provides functions for later retrieving the license and for destroying it.</p>
+
+ <div class="example">
+ <pre class="code">
+<script>
+ var keySystem;
+ var licenseUrl;
+ var mediaKeys;
+
+ // See the previous examples for implementations of these functions.
+ function selectKeySystem() { ... }
+ function sendMessage(message, keySession) { ... }
+ function handleMessage(event) { ... }
+ function handleError(event) { ... }
+
+ // Called if the application does not have a stored sessionId for the media resource.
+ function createSession(mediaKeys, initDataType, initData) {
+ mediaKeys.<premethodref>createSession</premethodref>(initDataType, initData, "persistent").then(
+ function(keySession) {
+ keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
+ keySession.addEventListener("<precoderef prefix="event">error</precoderef>", handleError, false);
+ keySession.close.then(
+ console.log.bind(console, "Session closed")
+ );
+ // Store keySession.<precoderef>sessionId</precoderef> in the application.
+ }
+ ).catch(
+ console.error.bind(console, "Unable to create or initialize a persistable key session")
+ );
+ }
+
+ // Called if the application has a stored sessionId for the media resource.
+ function loadStoredSession(mediaKeys, sessionId) {
+ mediaKeys.<premethodref>loadSession</premethodref>(sessionId).then(
+ function(keySession) {
+ if (!keySession) {
+ console.error("No stored session with the ID " + sessionId + " was found.");
+ return;
+ }
+ keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
+ keySession.addEventListener("<precoderef prefix="event">error</precoderef>", handleError, false);
+ keySession.close.then(
+ console.log.bind(console, "Session closed")
+ );
+ }
+ ).catch(
+ console.error.bind(console, "Unable to load or initialize the stored session with the ID " + sessionId)
+ );
+ }
+
+ // Called when the application wants to remove the license for the media resource.
+ removeStoredSession(keySession) {
+ keySession.<premethodref>release</premethodref>().catch(
+ console.error.bind(console, "Unable to release the session")
+ );
+ }
+
+ // This replaces the implementation in the previous example.
+ function handleMessageResponse(keySession, response) {
+ var license = new Uint8Array(response);
+ keySession.<premethodref>update</premethodref>(license).then(
+ function() {
+ // If this was the last required message from the server, the license is
+ // now stored. Update the application state as appropriate.
+ }
+ ).catch(
+ console.error.bind(console, "update() failed")
+ );
+ }
+
+ selectKeySystem();
+ <precoderef>MediaKeys</precoderef>.<premethodref>create</premethodref>(keySystem).then(
+ function(createdMediaKeys) {
+ mediaKeys = createdMediaKeys;
+ var video = document.getElementById("v");
+ return video.<premethodref>setMediaKeys</premethodref>(mediaKeys);
+ }
+ ).catch(
+ console.error.bind(console, "Unable to create or use new MediaKeys")
+ );
+</script>
+
+<video id="v" src="foo.webm" autoplay></video></pre>
+ </div>
+
<h2 id="revision-history">9. Revision History</h2>
<table>