- 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