- From: Martin Thomson <martin.thomson@gmail.com>
- Date: Mon, 25 Mar 2013 14:55:08 -0700
- To: "public-media-capture@w3.org" <public-media-capture@w3.org>
I think that it's fair to say that the current state of the MediaStream[Track] states is pretty dire. At least from a usability perspective. Let's take a quick inventory: MediaStreamTrack: attribute boolean enabled; readonly attribute MediaStreamTrackState readyState; attribute EventHandler onstarted; attribute EventHandler onmute; attribute EventHandler onunmute; attribute EventHandler onended; MediaStream: attribute boolean ended; attribute EventHandler onended; On the track we have two state variables, one of them writeable, and four events. At a bare minimum, this could be a single onstatechange event. For the stream, I really don't know why I would want to set ended = true on a stream. The explanation doesn't cast any light on the matter either. Let's pretend that this is read-only for the moment. Rendering I believe that the gUM document needs to be very clear about the rendering logic for MediaStream instances. This is a little too amorphous in the current document. I propose a section or sub-section entitled "Rendering MediaStreams" that has an explanation along the lines of the following. When a particular MediaStream instance is attached to a sink that consumes only one source (not a mixing sink, like <audio> probably will be), the output will be selected from the set of tracks in the stream that: - are "live"; that is, in a readyState of "muted" or "unmuted" (not "new" or "ended") - have enabled = true ...of course, media will only render (other than silence/black) if the selected track's readyState is "unmuted". I'm assuming here that track selection does not examine the muted/unmuted state. ...but only if the stream itself is not ended. Note that the stream can be un-ended by adding an un-ended track. A mixing sink (such as <audio>) renders multiple tracks simultaneously, combining all candidate tracks. Mute/unmute/enabled/disabled Again, specific treatment of this relationship might make it easier to understand. A sub-section that is explicitly on this subject would help. Specifically: A muted or disabled track renders either silence (audio), black frames (video), or a zero-information-content equivalent. Media flows only when a track is both unmuted and enabled. The muted/unmuted state of a track is under user control, the enabled/disabled state is under application control. A track can be muted by a user. Often this action is outside the control of the application. This could be as a result of the user hitting a hardware switch, toggling a control in the operating system or browser chrome, or as simple as throwing a hat over the camera. Not all muting/unmuting actions can be detected by the browser directly. When a track is muted or unmuted in a way that is detected by the browser, the browser fires a state change event [ref: actual event description] to inform the application. Applications are able to enable or disable tracks. This is logically equivalent to muting and unmuting, except that the application is in control and the enabled/disabled state operates independently of the muted/unmuted state. Muted/unmuted/"readyState" The lifecycle states of a track are now different to that of a stream. That might need fixing. (Advertise "new" on stream while all tracks are also "new"). But the key point I wanted to raise was that lifecycle and mute/unmute operate independently. They are orthogonal. Third-normal form dictates that we place these in different columns. Yes, I will concede that you don't care about the muted/unmuted state of a track in any state other than "live", that's not the point. It's hard to form thoughts about something, or explain it effectively if you conflate concepts. Proposal: MediaStreamTrack: attribute boolean enabled [= true]; readonly attribute boolean muted; readonly attribute LiveCycleStateEnum state = ["new" / "live" / "ended"]; attribute EventHandler onmute; // and unmute, attach a boolean to the event details attribute EventHandler onstatechange; // one handler per state variable, not 4 MediaStream: readonly attribute LiveCycleStateEnum state = ["new" / "live" / "ended"]; // where "new" or "ended" only if all tracks are in that state. attribute EventHandler onstatechange; // one handler per state variable, not 4 I can live with having mute+lifecycle states conflated. I can see how that would be convenient in some cases. It's only a reporting interface after all. No harm in doing the right thing from the outset though.
Received on Monday, 25 March 2013 21:55:36 UTC