- From: David Dorwin <ddorwin@google.com>
- Date: Wed, 27 Jun 2012 22:24:05 -0700
- To: public-html-media@w3.org
- Message-ID: <CAHD2rsjjujTuiubz8rP6g_s5JDFh4GLr7Y0hVaTRAfcM4PwM4A@mail.gmail.com>
This proposal relates to the discussion in [1] and bug [2] as well as others. In those discussions and the teleconference [3] this week, the group agreed to pursue a session object-based design for the API. This proposal is intended to provide a more concrete basis for discussion but is not intended to be final. There are still some open questions, which I have identified below the proposal. Please provide feedback, discuss, and provide input on the questions so we can try to close this issue during the teleconference in two weeks. If you have questions that aren't directly related to this proposal or questions (i.e. regarding the contents of initData) please start a new thread so we can keep this one focused. *Summary of Changes* - HTMLMediaElement has generateKeyRequest() and receives need key events/ - MediaKeySession has addKey() and close() and receives keymessage, keyadded, and keyerror events. - All methods have less parameters because some are now represented as attributes of the session object. - There are only two custom event types, both with fewer attributes. This is because keyadded and keyerror are simple events. - All error information is obtained from the error attribute of the session object. code and systemCode are members of MediaKeyError. This more closely matches MediaError. A couple caveats: - The proposal still uses video.generateKeyRequest() to create the object, though, that may change per http://lists.w3.org/Archives/Public/public-html-media/2012Jun/0134.html. - It does not currently define/support reuse of session objects as was discussed in the teleconference [3]. See http://lists.w3.org/Archives/Public/public-html-media/2012Jun/0133.html. *Changes* Below are updates of selected text from the original document. They show the most important changes related to this proposal. The following may not be readable in a plain text version of this email, so I've included a plain text version of it at the very end of my email. partial interface HTMLMediaElement { // Adds optional 'keySystem' parameter. DOMString canPlayType <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-canplaytype>(in DOMString type, in DOMstring? keySystem <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_key-system>); // key sessions MediaKeySession <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeysession> generateKeyRequest <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-generatekeyrequest>(in DOMString keySystem <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_key-system>, in Uint8Array? initData); }; interface MediaKeySession : EventTarget <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-eventtarget> { // error state readonly attribute MediaKeyError <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeyerror>? error <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-error>; // session properties readonly attribute DOMString keySystem <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-keysystem>; readonly attribute DOMString sessionId <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-sessionid>; // session operations void addKey <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-addkey>(in Uint8Array key); void close <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-close>(); }; partial interface HTMLSourceElement { attribute DOMString keySystem <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-sourcekeysystem>; }; The keySystem attribute is an identifier for the Key System<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_key-system> being used. The sessionId attribute is the Session ID<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_session-id> for this objects and the associated key(s) or license(s). The error attribute is a MediaKeyError<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeyerror> representing the current error state of the session. It is null if there is no error. interface MediaKeyError { const unsigned short MEDIA_KEYERR_UNKNOWN <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-media_keyerr_unknown> = 1; const unsigned short MEDIA_KEYERR_CLIENT <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-media_keyerr_client> = 2; const unsigned short MEDIA_KEYERR_SERVICE <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-media_keyerr_service> = 3; const unsigned short MEDIA_KEYERR_OUTPUT <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-media_keyerr_output> = 4; const unsigned short MEDIA_KEYERR_HARDWARECHANGE <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-media_keyerr_hardwarechange> = 5; const unsigned short MEDIA_KEYERR_DOMAIN <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-media_keyerr_domain> = 6; readonly attribute unsigned short code <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-code>; readonly attribute unsigned long systemCode <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-systemcode>; }; session . error . code<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-code> Returns the current error's error code, from the list below. session . error . systemCode<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-systemcode> Returns the current error's system code. The code attribute of a MediaKeySession<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeysession> object must return the code for the error, which must be one of the following: *...skipping unchanged error code text...* The systemCode attribute of a MediaKeySession<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeysession> object is a Key System<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_key-system>-dependent status code for the error that occurred. This allows a more granular status to be returned than the more general errorCode<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-errorcode> . It should be 0 if there is no associated status code or such status codes are not supported by the Key System. Events 3.1. Event Definitions [Constructor(DOMString type, optional MediaKeyMessageEventInit <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeymessageeventinit> eventInitDict)] interface MediaKeyMessageEvent : Event <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event> { readonly attribute Uint8Array message <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-message>; readonly attribute DOMString? destinationURL <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-destinationurl>; }; dictionary MediaKeyMessageEventInit : EventInit <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit> { Uint8Array message <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-message>; DOMString? destinationURL <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-destinationurl>; }; [Constructor(DOMString type, optional MediaKeyNeededEventInit <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeyneededeventinit> eventInitDict)] interface MediaKeyNeededEvent : Event <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event> { readonly attribute Uint8Array? initData <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-initdata>; }; dictionary MediaKeyNeededEventInit : EventInit <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit> { Uint8Array? initData <#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-initdata>; }; event . destinationURL<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-destinationurl> Returns the URL to send the message<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-message> to. event . initData<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-initdata> Returns the Initialization Data<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_initialization-data> related to the event. event . message<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-message> Returns the message (i.e. key request) to send. The initData attribute contains Initialization Data<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_initialization-data> specific to the event. The message attribute contains a message from the CDM. Messages are Key System-specific. In most cases, it should be sent to a key server. The destinationURL is the URL to send the message<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-message> to. An application *may* override this. In some cases, it may have been provided by the media data<http://dev.w3.org/html5/spec/video.html#media-data> . It may be null. If a response (i.e. a license) is necessary, applications should use one of the new methods<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-htmlmediaelement> to provide the response. 3.2. Event Summary The following events are fired at MediaKeySession<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeysession> . Event nameInterface Dispatched when...Preconditions keyadded Simple eventA key has been added as the result of a addKey()<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-addkey> call. keyerror Simple event An error occurs in the session. keymessage MediaKeyMessageEvent<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeymessageevent>A message has been generated (and likely needs to be sent to a server). For example, a key request has been generated as the result of agenerateKeyRequest()<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-generatekeyrequest> call or another message must be sent in response to an addKey()<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-addkey> call. The following event is fired at HTMLMediaElement<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-htmlmediaelement> . Event name InterfaceDispatched when... Preconditions needkey MediaKeyNeededEvent<#1383187a569bf054_138309ca0b801945_1383098cbd9c7783_13830982a754ed58_dom-mediakeyneededevent>The user agent needs a key or license to begin or continue playback. It may have encountered media data<http://dev.w3.org/html5/spec/video.html#media-data> that may/does require decryption to load or play OR need a new key/license to continue playback. readyState<http://dev.w3.org/html5/spec/video.html#dom-media-readystate> is equal to HAVE_METADATA<http://dev.w3.org/html5/spec/video.html#dom-media-have_metadata> or greater. It is possible that the element is playing or has played. *Other Text Additions and Notes* - generateKeyRequest() returns null if keySystem is not supported. Even if a valid object is returned, an error may still occur. Applications should handle the keyerror event upon creation to detect such errors. - CDMs must always fire a keymessage or keyerror after generateKeyRequest() unless a null object was returned. - The CDM should treat all key identifiers in the initData the same. That is, it should generate a license request for all of them. <non-normative>For example, regardless of whether one or more of the key IDs is already known in a different session. In addition to being simpler, this avoids potential problems if the other session is closed.</non-normative> - Note: Session IDs are required. (For consistency and because it is simple to implement.) - Note: Each initData value, whether it be from the same stream or multiple streams (e.g. audio and video) must be in a separate session object and thus has a different session ID. In most cases, generateKeyRequest() will return a valid object and fire either a keymessage or keyerror event at it. Therefore, applications should register handlers for the object as soon as it is created. For example: var session = video.generateKeyRequest(keySystem, initData); if (session) { session.onkeymessage = handleKeyMessage; session.onkeyerror = handleKeyError; } *Referencing the Element for a Session* There was a request in the teleconference to have a link back to the media element. I do not think we need or should add this because the application can handle this if it wants and it may present problems if we choose to allow sharing of sessions among elements in the future. An application might perform this association as shown below. var session = video.generateKeyRequest(keySystem, initData); if (session) session.element = video; The application can then use this.element in the event handlers. *Bugs Addressed* This change addresses the following bugs: - https://www.w3.org/Bugs/Public/show_bug.cgi?id=16548 - Enforces that generateKeyRequest() is called in all cases [before addKey()] without any additional logic. - https://www.w3.org/Bugs/Public/show_bug.cgi?id=16549 - initData parameter can be removed from addKey. - https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550 - sessionId parameter is eliminated, so checking them is obsolete. - https://www.w3.org/Bugs/Public/show_bug.cgi?id=16612 - All methods except the creation method are in a new object interface. - https://www.w3.org/Bugs/Public/show_bug.cgi?id=16613 - Sessions are represented as objects. - https://www.w3.org/Bugs/Public/show_bug.cgi?id=16614 - initData, generateKeyRequest() calls, their responses, and all subsequent messages and addKey calls can all be easily correlated. - https://www.w3.org/Bugs/Public/show_bug.cgi?id=17203 - We require session IDs for all key systems. *Open Questions* 1. Should we create the object using "new MediaKeySession" rather than video.generateKeyRequest()? See http://lists.w3.org/Archives/Public/public-html-media/2012Jun/0134.html. 2. Should we support reuse of session objects? See http://lists.w3.org/Archives/Public/public-html-media/2012Jun/0133.html. 3. Do user agents need to support sessions objects from support multiple key systems on the same element? 1. There is nothing preventing this in the proposal, but it seems like a problem for implementations. It would definitely make the Chrome implementation more complex. 4. Is sessionId valid upon creation of the object or only after the first keymessage is received? 1. The former is simplest to reason about but requires that the session IDs be allocated synchronously (and possibly by the user agent instead of the CDM). 5. Do we still need a cancel()/close() method on the session object or is destroying the object (after garbage collection) sufficient? 1. Is the answer to the above questions sufficient for explicitly destroying the keys ( https://www.w3.org/Bugs/Public/show_bug.cgi?id=16547)? 6. Should we allow session objects to be shared ( https://www.w3.org/Bugs/Public/show_bug.cgi?id=16615 and https://www.w3.org/Bugs/Public/show_bug.cgi?id=17202)? 1. We could punt on this until we have real use cases, but some decisions we make now may affect this. For example, see question #1. 7. Should we drop "key" from the name of events now fired at the object? 1. "key" is implicit since they are fired at a key session object. 2. However, it may be easier to discuss "keyerror" events rather than just "error" events, which could refer to any object. Specifically, it might be confused with http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#event-media-error . [1] http://lists.w3.org/Archives/Public/public-html-media/2012Jun/0054.html [2] https://www.w3.org/Bugs/Public/show_bug.cgi?id=16613 [3] http://www.w3.org/2012/06/26-html-media-minutes.html ========== Begin Plain Text Version of Changes Section ========== partial interface HTMLMediaElement { // Adds optional 'keySystem' parameter. DOMString canPlayType(in DOMString type, in DOMstring? keySystem); // key sessions MediaKeySession generateKeyRequest(in DOMString keySystem, in Uint8Array? initData); }; interface MediaKeySession : EventTarget { // error state readonly attribute MediaKeyError? error; // session properties readonly attribute DOMString keySystem; readonly attribute DOMString sessionId; // session operations void addKey(in Uint8Array key); void close(); }; partial interface HTMLSourceElement { attribute DOMString keySystem; }; The keySystem attribute is an identifier for the Key System being used. The sessionId attribute is the Session ID for this objects and the associated key(s) or license(s). The error attribute is a MediaKeyError representing the current error state of the session. It is null if there is no error. interface MediaKeyError { const unsigned short MEDIA_KEYERR_UNKNOWN = 1; const unsigned short MEDIA_KEYERR_CLIENT = 2; const unsigned short MEDIA_KEYERR_SERVICE = 3; const unsigned short MEDIA_KEYERR_OUTPUT = 4; const unsigned short MEDIA_KEYERR_HARDWARECHANGE = 5; const unsigned short MEDIA_KEYERR_DOMAIN = 6; readonly attribute unsigned short code; readonly attribute unsigned long systemCode; }; session . error . code Returns the current error's error code, from the list below. session . error . systemCode Returns the current error's system code. The code attribute of a MediaKeySession object must return the code for the error, which must be one of the following: ...skipping unchanged error code text... The systemCode attribute of a MediaKeySession object is a Key System-dependent status code for the error that occurred. This allows a more granular status to be returned than the more general errorCode. It should be 0 if there is no associated status code or such status codes are not supported by the Key System. Events 3.1. Event Definitions [Constructor(DOMString type, optional MediaKeyMessageEventInit eventInitDict)] interface MediaKeyMessageEvent : Event { readonly attribute Uint8Array message; readonly attribute DOMString? destinationURL; }; dictionary MediaKeyMessageEventInit : EventInit { Uint8Array message; DOMString? destinationURL; }; [Constructor(DOMString type, optional MediaKeyNeededEventInit eventInitDict)] interface MediaKeyNeededEvent : Event { readonly attribute Uint8Array? initData; }; dictionary MediaKeyNeededEventInit : EventInit { Uint8Array? initData; }; event . destinationURL Returns the URL to send the message to. event . initData Returns the Initialization Data related to the event. event . message Returns the message (i.e. key request) to send. The initData attribute contains Initialization Data specific to the event. The message attribute contains a message from the CDM. Messages are Key System-specific. In most cases, it should be sent to a key server. The destinationURL is the URL to send the message to. An application may override this. In some cases, it may have been provided by the media data. It may be null. If a response (i.e. a license) is necessary, applications should use one of the new methods to provide the response. 3.2. Event Summary The following events are fired at MediaKeySession. Event name Interface Dispatched when... Preconditions keyadded Simple event A key has been added as the result of a addKey() call. keyerror Simple event An error occurs in the session. keymessage MediaKeyMessageEvent A message has been generated (and likely needs to be sent to a server). For example, a key request has been generated as the result of agenerateKeyRequest() call or another message must be sent in response to an addKey() call. The following event is fired at HTMLMediaElement. Event name Interface Dispatched when... Preconditions needkey MediaKeyNeededEvent The user agent needs a key or license to begin or continue playback. It may have encountered media data that may/does require decryption to load or play OR need a new key/license to continue playback. readyState is equal to HAVE_METADATA or greater. It is possible that the element is playing or has played.
Received on Thursday, 28 June 2012 05:24:57 UTC